PK!Aradar_server/__init__.pyfrom .exceptions import * from . import fields from .query import query from .resolver import resolver from .record import record from .union import union from . import utils PK!5üradar_server/exceptions.pyclass FieldNotFound(Exception): pass class MissingRecordKey(Exception): pass class EmptyRecordKey(Exception): pass class TooManyRecordKeys(Exception): pass class QueryErrors(Exception): def __init__(self, *messages, code=None): self.messages = messages def for_json(self): return [ message if hasattr(message, 'for_json') is False else message for message in self.messages ] class RecordIsNull(Exception): pass PK!GAttradar_server/fields/__init__.pyfrom .array import array from .field import field from .mapping import mapping def boolean(*a, cast=bool, **kw): return field(*a, cast=cast, **kw) def single(*a, cast=float, **kw): return field(*a, cast=cast, **kw) def integer(*a, cast=int, **kw): return field(*a, cast=cast, **kw) def string(*a, cast=str, **kw): return field(*a, cast=cast, **kw) PK!radar_server/fields/array.pyfrom functools import wraps from .field import field __all__ = 'array', def cast_array(cast): @wraps(cast) def apply(value): return list(map(cast, value)) return apply def array(*a, cast=str, **kw): return field(*a, cast=cast_array(cast), **kw)PK!\Y LLradar_server/fields/field.pyfrom ..record import record_repr from ..query import query_repr __all__ = 'field', def default_cast(x): return x def default_resolver(state, field_name, record=None, query=None, query_name=None, **context): try: return state[field_name] except (KeyError, TypeError): query_ref = '' record_ref = '' if query_name is not None: query_ref = query_name elif query is not None: query_ref = f' of {query_repr(query)}' if record is not None: record_ref = f' in {record_repr(record)}' raise KeyError(f'Field `{field_name}` not found{record_ref}{query_ref}.') def field( resolver=default_resolver, default=None, cast=default_cast, not_null=False, key=False, ): def init(name): def resolve(state, **context): value = resolver(state, name, **context) if value is not None: return cast(value) else: if default is None: if not_null: raise ValueError(f'field `{name}` cannot be null.') else: return None else: return default # setattr(resolve, 'name', key) resolve.key = key return resolve return init PK!Nradar_server/fields/mapping.pyfrom ..exceptions import FieldNotFound from ..utils import to_js_key, bind from .field import field __all__ = 'mapping', def mapping(**mapping_fields): mapping_fields = bind(mapping_fields) if not len(mapping_fields): raise ValueError('Mappings cannot be empty') def get_resolvers(fields): if not fields: for field_name, resolve in mapping_fields.items(): yield to_js_key(field_name), resolve else: for field_name in fields: yield to_js_key(field_name), mapping_fields[field_name] def default_resolver(state, name, fields=None, **context): if state.get(name) is None: return None return { field_name: resolve(state[name], **context) for field_name, resolve in get_resolvers(fields) } def create_mapping(resolver=default_resolver, *a, key=None, **kw): if resolver != default_resolver: resolver = resolver(mapping_fields) if key: raise ValueError('Mappings cannot be Key fields.') return field(resolver, *a, **kw) return create_mapping PK!a-[ radar_server/query.pyfrom functools import wraps from .exceptions import RecordIsNull from .utils import to_py_key, to_py_deep, to_js_key, get_repr, bind __all__ = 'query', 'query_repr' empty_tuple = tuple() def query_repr(interface): return get_repr('Record', interface) def recursive_require(required, fields): out = {} for field_name, field in required.items(): if field is None or not len(field): # out[field_name] = recursive_require(fields[field_name], fields[field_name].fields) if hasattr(fields[field_name], 'fields'): out[field_name] = recursive_require( {key: None for key in fields[field_name].fields}, fields[field_name].fields ) else: out[field_name] = None else: out[field_name] = recursive_require(required[field_name], fields[field_name].fields) return out def query(**fields): query_records = bind(fields) empty_requires = {record_name: None for record_name in query_records.keys()} def create_query(resolver): wrapper = wraps(resolver) @wrapper def init(query_name): @wrapper def resolve(required=None, props=None, context=None): context = context or {} if required is not None and len(required): required = to_py_deep(required) required = recursive_require(required or empty_requires, query_records) if props is not None and len(props): state = resolver( required, query=query_records, query_name=query_name, **to_py_deep(props), **context ) else: state = resolver( required, query=query_records, query_name=query_name, **context ) values = {} for record_name, required_fields in required.items(): try: result = query_records[record_name]( state[record_name], required_fields, query=query_records, query_name=query_name, **context ) except RecordIsNull: result = None values[to_js_key(record_name)] = result return values return resolve return init return create_query PK!qradar_server/record.pyfrom .exceptions import RecordIsNull, EmptyRecordKey, MissingRecordKey, TooManyRecordKeys from .utils import to_js_key, get_repr, bind __all__ = 'record', 'default_resolver', 'resolve_many' def record_repr(interface): return get_repr('Record', interface) def default_resolver(state, name, index=None, **context): if context.get('record') is not None: state = state[name] if state is None: raise RecordIsNull() if index is None: return state else: return state[index] def resolve_many(resolve_one): def wrapper(*a, index=None, **kw): index = 0 values = [] add_values = values.append while True: try: add_values(resolve_one(*a, index=index, **kw)) except IndexError: break index += 1 return values return wrapper def record(**fields): record_fields = bind(fields) KEY = None for field_name, field in record_fields.items(): if hasattr(field, 'key') and field.key is True: if KEY is not None: raise TooManyRecordKeys( f'A record can only have one Key field in: {record_repr(record_fields)}' ) KEY = field_name if KEY is None: raise MissingRecordKey(f'{record_repr(record_fields)} does not have a Key field.') def resolve_field(state, field_name, fields=None, record=None, **context): field = record_fields[field_name] try: return field(state, fields=fields, record=record_fields, **context) except RecordIsNull: return None def resolve_fields(state, fields, **context): if not fields: for field_name, field in record_fields.items(): yield to_js_key(field_name), resolve_field(state, field_name, **context) else: fields = fields.items() if hasattr(fields, 'items') else fields for field_name, nested_fields in fields: if nested_fields is not None: yield ( to_js_key(field_name), resolve_field(state, field_name, fields=nested_fields, **context) ) else: yield to_js_key(field_name), resolve_field(state, field_name, **context) def create_record(resolver=default_resolver, many=False): def init(record_name): def resolve_one(state, fields=None, index=None, **context): state = resolver(state, record_name, fields=fields, index=index, **context) or {} if not isinstance(state, dict): raise TypeError( 'State returned by `resolver` functions must be of type' f'`dict`. "{state}" is not a dict in: {record_repr(record_fields)}' ) values = dict(resolve_fields(state, fields, **context)) key_name = to_js_key(KEY) if key_name not in values: try: values[key_name] = resolve_field(state, KEY, fields=fields, **context) except KeyError: values[key_name] = None if values[key_name] is None: raise EmptyRecordKey( f'{record_repr(record_fields)} did not have a ' 'Key field with a value. Your Key field must not return None.' ) return values resolve_ = resolve_many(resolve_one) if many is True else resolve_one resolve_.fields = record_fields return resolve_ init.fields = record_fields return init create_record.fields = record_fields return create_record PK! radar_server/resolver.pytry: import ujson as json except ImportError: import json import functools from .exceptions import QueryErrors from .query import query as create_query from .utils import bind __all__ = 'resolver', def resolver(**queries): radar_queries = bind(queries) def add_query(**kw): query = create_query(**kw) def wrapper(resolver): name = resolver.__name__ radar_queries[name] = functools.wraps(resolver)(query(resolver)(name)) return radar_queries[name] return wrapper def resolve_query(op, context): query = radar_queries[op['name']] requires = op.get('requires') props = op.get('props') try: return query(requires, props, context) except QueryErrors as e: return {'isRadarError': True, 'error': e.for_json()} def resolve(ops, **context): ops = json.loads(ops) if isinstance(ops, str) else ops if not ops: return ops if isinstance(ops, dict): return resolve_query(ops, context) else: return [resolve_query(op, context) for op in ops] resolve.queries = radar_queries resolve.query = add_query return resolve PK!APradar_server/union.pyfrom .exceptions import RecordIsNull from .record import default_resolver, resolve_many from .utils import get_repr, to_js_key, bind __all__ = 'union', 'union_repr' def union_repr(interface): return get_repr('union', interface) def union(resolve_member_name, **fields): union_members = bind(fields) def create_union(resolver=default_resolver, many=False): def init(union_name): def resolve_member(state, fields=None, index=None, record=None, **context): state = resolver( state, union_name, fields=fields, index=index, record=record, **context ) or {} if not isinstance(state, dict): raise TypeError( 'Data returned by `resolver` functions must be of type `dict`. ' f'"{state}" is not a dict in: {union_repr(union_members)}' ) record_type = resolve_member_name(state, fields=fields, **context) if record_type is None: raise TypeError( 'The `resolve_member_name` function did not return a string in: ' + union_repr(union_members) ) field = union_members[record_type] try: fields = None if fields is None else fields.get(record_type) return {to_js_key(record_type): field(state, fields=fields, **context)} except RecordIsNull: return {to_js_key(record_type): None} resolve_ = resolve_many(resolve_member) if many is True else resolve_member resolve_.fields = union_members return resolve_ init.fields = union_members return init create_union.fields = union_members return create_union PK! E! radar_server/utils.pyfrom trie_memoize import memoize __all__ = 'bind', 'get_repr', 'to_js_key', 'to_py_key', 'to_py_deep' def bind(fields): return {name: field_obj(name) for name, field_obj in fields.items()} def get_repr(name, interface): return f'{name}({", ".join(interface.keys())})' @memoize(dict) def to_js_key(key): if key.isupper(): return key r = key[0] has_alpha = False for i, char in enumerate(key[1:], 1): if char.isupper(): r += char has_alpha = True elif char == '_': try: next_char = key[i + 1] except IndexError: next_char = False try: prev_char = key[i - 1] except IndexError: prev_char = False if next_char and next_char != '_' and prev_char != '_': continue else: r += char else: try: prev_char = key[i - 1] except IndexError: prev_char = False try: prev_r_char = r[-1] except: prev_r_char = False if prev_char == '_' and has_alpha: if prev_r_char == '_': r = r[:-1] r += char.upper() else: r += char has_alpha = True return r @memoize(dict) def to_py_key(key): if key.isupper() or key.islower(): return key r = key[0] has_alpha = False for i, char in enumerate(key[1:], 1): if char.isupper(): try: prev_char = key[i - 1] except IndexError: prev_char = False if has_alpha is False and prev_char == '_': r += char has_alpha = True continue try: if key[i + 1].isupper() and prev_char: if not prev_char.isupper() and key[i - 1]: r += '_' r += char has_alpha = True continue except IndexError: pass try: if prev_char.isupper() and (i == len(key) - 1 or key[i + 1] == '_'): r += char has_alpha = True continue if prev_char.islower() or key[i + 1].islower(): r += '_' except IndexError: pass has_alpha = True if char != '_': has_alpha = True r += char.lower() return r def to_py_deep(props): return { to_py_key(key): val if not isinstance(val, dict) else to_py_deep(val) for key, val in props.items() } PK!HAJ`",5-radar_server-0.1.5.dist-info/entry_points.txtN+I/N.,()JJKΰVy\%%Ŷ`"PK!QP55$radar_server-0.1.5.dist-info/LICENSEThe MIT License (MIT) Copyright (c) 2017 Jared Lunde Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.PK!Hu)GTU"radar_server-0.1.5.dist-info/WHEEL HM K-*ϳR03rOK-J,/R(O-)$qzd&Y)r$UV&UrPK!H/P%radar_server-0.1.5.dist-info/METADATARMO1W4 . 4@D8A%B˵ɫFf i\钍JxT&=p'jU|osu Vcf^ Ud2e$XL(bg }Zr>./jOR}ˏ+;Vqq)HqB‚ pPwnSّ@X)(*8˪|R}cت@Xqe d7PK!H #radar_server-0.1.5.dist-info/RECORD˒:~p.gJ:-@}cѷ֟$4#CF&I $+?&w*(lwwMdsVfIݑfk@yuh1}=UrƩ> dfƇ]K'ZUeNԯb^duJZ$COJ[:Æik⹧Q$("B"|b񁮆UC^UzdZ49?/&;wWKh ,p|tZL+APCI6 |yar 9?~aCZЬ9o2tMFq ۺXs?1TI0Ⱥ ]#ٹ%mrpaN;FԨᑰtOn"p9Ik9 (U[,V '%T~YQ7k鵬 ػuSec[r OԴ%ƍֹ&+n|xUj oIz˄mUNTxaf,-( 3=3:c8NUQkpN CC8)r39.d)3nzI*8>ޗiˣ,lO~< @}FܳwCradar_server-0.1.5.dist-info/LICENSEPK!Hu)GTU"Gradar_server-0.1.5.dist-info/WHEELPK!H/P%IHradar_server-0.1.5.dist-info/METADATAPK!H #Iradar_server-0.1.5.dist-info/RECORDPKL