<commit_before>
import json
import traceback
from werkzeug.routing import Rule
from . import sessions
from fladgejt.helpers import encode_key, decode_key


def decode_args(method, args):
    spec = getattr(method, 'key_args', None)
    if not spec: return args
    return tuple(decode_key(arg) if is_key and isinstance(arg, str) else arg
                 for arg, is_key in zip(args, spec))


def encode_result(thing):
    if (isinstance(thing, tuple) and hasattr(thing, '_replace') and
        hasattr(thing, 'key')):
        thing = thing._replace(key=encode_key(thing.key))
    if isinstance(thing, tuple) and hasattr(thing, '_asdict'):
        thing = thing._asdict()

    if isinstance(thing, (list, tuple)):
        return [encode_result(item) for item in thing]
    if isinstance(thing, dict):
        return { key: encode_result(value) for key, value in thing.items() }
    return thing


def rpc_handle_call(request, session):
    name = request.args['name']
    args = json.loads(request.get_data(as_text=True))
    method = getattr(session['client'], name)

    args = decode_args(method, args)
    return encode_result(method(*args))


def rpc_handle_sessions(request, send_json):
    if not sessions.get_cookie(request):
        raise ValueError('Session cookie not found')

    def custom_log(type, message, data=None):
        send_json({ 'log': type, 'message': message })
        # TODO: also write to log file.

    with sessions.transaction(request) as session:
        if request.headers.get('X-CSRF-Token') != session['csrf_token']:
            raise ValueError('Bad X-CSRF-Token value')<commit_msg>Add rpc logging.<commit_after>
import json
import traceback
from werkzeug.routing import Rule
from . import sessions
from fladgejt.helpers import encode_key, decode_key


def decode_args(method, args):
    spec = getattr(method, 'key_args', None)
    if not spec: return args
    return tuple(decode_key(arg) if is_key and isinstance(arg, str) else arg
                 for arg, is_key in zip(args, spec))


def encode_result(thing):
    if (isinstance(thing, tuple) and hasattr(thing, '_replace') and
        hasattr(thing, 'key')):
        thing = thing._replace(key=encode_key(thing.key))
    if isinstance(thing, tuple) and hasattr(thing, '_asdict'):
        thing = thing._asdict()

    if isinstance(thing, (list, tuple)):
        return [encode_result(item) for item in thing]
    if isinstance(thing, dict):
        return { key: encode_result(value) for key, value in thing.items() }
    return thing


def rpc_handle_call(request, session):
    name = request.args['name']
    args = json.loads(request.get_data(as_text=True))
    log = session['client'].context.log

    log('rpc', 'RPC {} started'.format(name), args)
    try:
        method = getattr(session['client'], name)
        args = decode_args(method, args)
        result = encode_result(method(*args))
    except Exception as e:
        log('rpc', 'RPC {} failed with {}'.format(name, type(e).__name__),
            traceback.format_exc())
        raise
    log('rpc', 'RPC {} finished'.format(name), result)
    return result


def rpc_handle_sessions(request, send_json):
    if not sessions.get_cookie(request):
        raise ValueError('Session cookie not found')

    def custom_log(type, message, data=None):
        send_json({ 'log': type, 'message': message })
        # TODO: also write to log file.

    with sessions.transaction(request) as session:
        if request.headers.get('X-CSRF-Token') != session['csrf_token']:
            raise ValueError('Bad X-CSRF-Token value')
{'fraction_non_alphanumeric': 0.12029025955902875, 'fraction_numerical': 0.0, 'mean_word_length': 3.4744069912609237, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1306991', 'n_tokens_mistral': 1080, 'n_tokens_neox': 1073, 'n_words': 306}