<commit_before>import json
from functools import partial
from datetime import datetime, date

import trafaret as t
from aiohttp import web

from .exceptions import JsonValidaitonError
from .consts import TEMPLATES_ROOT

try:
    from bson import ObjectId
except ImportError:
    ObjectId = None


__all__ = ['json_response', 'validate_query', 'gather_template_folders']


def json_datetime_serial(obj):
    """JSON serializer for objects not serializable by default json code"""
    if isinstance(obj, (datetime, date)):
        serial = obj.isoformat()
        return serial

    if ObjectId is not None and isinstance(obj, ObjectId):
        # TODO: try to use bson.json_util instead
        return str(obj)

    raise TypeError("Type not serializable")


jsonify = partial(json.dumps, default=json_datetime_serial)

json_response = partial(web.json_response, dumps=jsonify)


OptKey = partial(t.Key, optional=True)


SimpleType = t.Int | t.Bool | t.String | t.Float
Filter = t.Dict({
    OptKey('in'): t.List(SimpleType),
    OptKey('gt'): SimpleType,
    OptKey('ge'): SimpleType,
    OptKey('lt'): SimpleType,
    OptKey('le'): SimpleType,
    OptKey('ne'): SimpleType,
    OptKey('eq'): SimpleType,
    OptKey('like'): SimpleType,
})

ListQuery = t.Dict({
    t.Key('_page', default=1): t.Int[1:],
    t.Key('_perPage', default=30): t.Int[1:],
    OptKey('_sortField', default='id'): t.String,
    OptKey('_sortDir'): t.Enum('DESC', 'ASC'),
    OptKey('_filters'): t.Mapping(t.String, Filter | SimpleType)
})


def validate_query(query):
    query_dict = dict(query)
    filters = query_dict.pop('_filters', None)
    if filters:<commit_msg>proper trafaret for query arguments<commit_after>import json
from functools import partial
from datetime import datetime, date

import trafaret as t
from aiohttp import web

from .exceptions import JsonValidaitonError
from .consts import TEMPLATES_ROOT

try:
    from bson import ObjectId
except ImportError:
    ObjectId = None


__all__ = ['json_response', 'validate_query', 'gather_template_folders']


def json_datetime_serial(obj):
    """JSON serializer for objects not serializable by default json code"""
    if isinstance(obj, (datetime, date)):
        serial = obj.isoformat()
        return serial

    if ObjectId is not None and isinstance(obj, ObjectId):
        # TODO: try to use bson.json_util instead
        return str(obj)

    raise TypeError("Type not serializable")


jsonify = partial(json.dumps, default=json_datetime_serial)

json_response = partial(web.json_response, dumps=jsonify)


OptKey = partial(t.Key, optional=True)


SimpleType = t.Int | t.Bool | t.String | t.Float
Filter = t.Dict({
    OptKey('in'): t.List(SimpleType),
    OptKey('gt'): SimpleType,
    OptKey('ge'): SimpleType,
    OptKey('lt'): SimpleType,
    OptKey('le'): SimpleType,
    OptKey('ne'): SimpleType,
    OptKey('eq'): SimpleType,
    OptKey('like'): SimpleType,
})


ASC = 'ASC'
DESC = 'DESC'
ListQuery = t.Dict({
    OptKey('_page', default=1): t.Int[1:],
    OptKey('_perPage', default=30): t.Int[1:],
    OptKey('_sortField'): t.String,
    OptKey('_sortDir', default=DESC): t.Enum(DESC, ASC),

    OptKey('_filters'): t.Mapping(t.String, Filter | SimpleType)
})


def validate_query(query):
    query_dict = dict(query)
    filters = query_dict.pop('_filters', None)
    if filters:
{'fraction_non_alphanumeric': 0.1298623578695392, 'fraction_numerical': 0.002992220227408737, 'mean_word_length': 4.166924265842349, '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': '7353491', 'n_tokens_mistral': 1092, 'n_tokens_neox': 1067, 'n_words': 285}