示例#1
0
class ConsoleLoggerInterface(LoggerInterface):
    def __init__(self, name, level=None, style=None):
        super().__init__(name, level=level)
        self._json = JsonEncoder()
        self._style = style or 'json'

    def process_message(self, level: Text, message: Text, data: Dict) -> Text:
        when = TimeUtils.utc_now().strftime('%m/%d/%Y %H:%M:%S')
        level = level.upper()[0]

        if data:
            data = self._json.decode(self._json.encode(data))
            if self._style == 'json':
                dumped_data = self._to_json(data)
            elif self._style == 'yaml':
                dumped_data = self._to_yaml(data)
            else:
                raise ValueError(f'unrcognized log style: {self.style}')
        else:
            dumped_data = None

        thread = StringUtils.dash(current_thread().name)

        display_string = (f'{when} ({level}) {self._name}' f' - {message}')
        if dumped_data:
            display_string += f'\n\n{dumped_data}\n'
        return display_string

    def _to_json(self, data):
        return json.dumps(data, indent=2, sort_keys=True)

    def _to_yaml(self, data):
        lines = yaml.dump(data, default_flow_style=False).split('\n')
        return '\n'.join('  ' + line for line in lines)
示例#2
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.encoder = JsonEncoder()
     self.field_2_index_type = {
         fields.String: StringIndex,
         fields.Int: NumericIndex,
         fields.Float: NumericIndex,
         fields.DateTime: NumericIndex,
         fields.Timestamp: NumericIndex,
         fields.Uuid: NumericIndex,
         fields.Bool: NumericIndex,
     }
示例#3
0
 def read_body_json_object(self):
     body = {}
     content_len = int(self.headers.get('content-length', 0))
     if content_len:
         body_bytes = self.rfile.read(content_len)
         if body_bytes:
             body = JsonEncoder.decode(body_bytes.decode())
     return body
示例#4
0
文件: aes.py 项目: gigaquads/ravel
class AES:
    def __init__(self, key: Text = None, iv: bytes = None):
        self.json = JsonEncoder()
        self.iv = iv or get_random_bytes(16)
        self.key = (key or random_uuid().hex).encode('utf-8')

    def encrypt_CBC(self, value: object) -> Text:
        json_str = self.json.encode(value).encode('utf-8')
        cipher = AES_Cipher.new(self.key, AES_Cipher.MODE_CBC, self.iv)
        enc_bytes = cipher.encrypt(pad(json_str, AES_Cipher.block_size))
        return b64encode(enc_bytes).decode('utf-8')

    def decrypt_CBC(self, encrypted_value: Text) -> object:
        cipher = AES_Cipher.new(self.key, AES_Cipher.MODE_CBC, self.iv)
        enc_bytes = b64decode(encrypted_value.encode('utf-8'))
        json_str = unpad(cipher.decrypt(enc_bytes), AES_Cipher.block_size)
        return self.json.decode(json_str)
示例#5
0
    def fetch_many(self, _ids: List, fields: Set[Text] = None) -> Dict:
        pipe = self.redis.pipeline()

        self.records.get_many(_ids, pipe=pipe)
        self.revs.get_many(_ids, pipe=pipe)

        json_records, rev_strs = pipe.execute()

        fields = fields if isinstance(fields, set) else set(fields or [])
        records = {}

        if fields:
            for record_json, _rev in zip(json_records, rev_strs):
                record = JsonEncoder.decode(record_json)
                record = {k: record.get(k) for k in fields}
                record[REV] = int(_rev) - 1
                records[record[ID]] = record
        else:
            for record_json, _rev in zip(json_records, rev_strs):
                record = JsonEncoder.decode(record_json)
                record[REV] = int(_rev) - 1
                records[record[ID]] = record

        return records
示例#6
0
    def query(self, predicate: 'Predicate', **kwargs):
        if predicate is None:
            _ids = self.records.keys()
        else:
            _ids = self.query_ids(predicate)

        records = []

        if _ids:
            _id_field = self.resource_type.Schema.fields[ID]
            json_records = self.records.get_many(_ids)
            rev_strs = self.revs.get_many(_ids)
            for json_record, rev_str in zip(json_records, rev_strs):
                record = JsonEncoder.decode(json_record)
                record[REV] = int(rev_str.decode())
                records.append(record)

        return records
示例#7
0
    def fetch(self, _id, fields: Set[Text] = None) -> Dict:
        fields = fields if isinstance(fields, set) else set(fields or [])

        pipe = self.redis.pipeline()

        self.records.get(_id)
        self.revs.get(_id)

        record_json, rev_str = pipe.execute()

        if not record_json:
            return None

        full_record = JsonEncoder.decode(record_json)
        full_record[REV] = int(rev_str) - 1

        if fields:
            return {k: full_record.get(k) for k in fields}
        else:
            return full_record
示例#8
0
    def __init__(
        self,
        middleware: List['Middleware'] = None,
        manifest: Manifest = None,
        mode: Mode = Mode.normal,
    ):
        # thread-local storage
        self.local = local()
        self.local.is_bootstrapped = False
        self.local.is_started = False
        self.local.manifest = Manifest(manifest) if manifest else None
        self.local.bootstrapper_thread_id = None
        self.local.thread_executor = None
        self.local.process_executor = None
        self.local.tx_manager = None

        self.shared = DictObject()  # storage shared by threads
        self.shared.manifest_data = None
        self.shared.app_counter = 1

        self.env = Environment()
        self._mode = mode
        self._json = JsonEncoder()
        self._binder = ResourceBinder()
        self._namespace = {}
        self._arg_loader = None
        self._logger = None
        self._root_pid = os.getpid()
        self._actions = DictObject()

        self._middleware = deque([
            m for m in (middleware or [])
            if isinstance(self, m.app_types)
        ])

        # set default main thread name
        current_thread().name = (
            f'{get_class_name(self)}MainThread'
        )
示例#9
0
class RedisStore(Store):

    redis = None
    host = 'localhost'
    port = 6379
    db = 0

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.encoder = JsonEncoder()
        self.field_2_index_type = {
            fields.String: StringIndex,
            fields.Int: NumericIndex,
            fields.Float: NumericIndex,
            fields.DateTime: NumericIndex,
            fields.Timestamp: NumericIndex,
            fields.Uuid: NumericIndex,
            fields.Bool: NumericIndex,
        }

    @classmethod
    def on_bootstrap(cls, host=None, port=None, db=None):
        cls.host = host or cls.env.REDIS_HOST or cls.host
        cls.port = port or cls.env.REDIS_PORT or cls.port
        cls.db = db if db is not None else (cls.env.REDIS_DB or cls.db)
        cls.redis = RedisClient(host=cls.host, port=cls.port, db=cls.db)

    def on_bind(self, resource_type: Type['Resource'], **kwargs):
        self.type_name = StringUtils.snake(resource_type.__name__).lower()
        self.records = HashSet(self.redis, self.type_name)
        self.revs = HashSet(self.redis, f'{self.type_name}_revisions')
        self.indexes = self._bind_indexes()

    def _bind_indexes(self):
        indexes = {}
        for k, field in self.resource_type.Schema.fields.items():
            index_name = f'{self.type_name}:{k.lower()}'
            index_type = self.field_2_index_type.get(field.__class__)
            if index_type is None:
                index_type = StringIndex
            indexes[k] = index_type(self.redis, index_name)
        return indexes

    def exists(self, _id) -> bool:
        return (_id in self.records)

    def exists_many(self, _ids: Set) -> Dict[object, bool]:
        return {
            _id: (_id in self.records)
            for _id in _ids
        }

    def count(self) -> int:
        return len(self.records)

    def fetch(self, _id, fields: Set[Text] = None) -> Dict:
        fields = fields if isinstance(fields, set) else set(fields or [])

        pipe = self.redis.pipeline()

        self.records.get(_id)
        self.revs.get(_id)

        record_json, rev_str = pipe.execute()

        if not record_json:
            return None

        full_record = JsonEncoder.decode(record_json)
        full_record[REV] = int(rev_str) - 1

        if fields:
            return {k: full_record.get(k) for k in fields}
        else:
            return full_record

    def fetch_many(self, _ids: List, fields: Set[Text] = None) -> Dict:
        pipe = self.redis.pipeline()

        self.records.get_many(_ids, pipe=pipe)
        self.revs.get_many(_ids, pipe=pipe)

        json_records, rev_strs = pipe.execute()

        fields = fields if isinstance(fields, set) else set(fields or [])
        records = {}

        if fields:
            for record_json, _rev in zip(json_records, rev_strs):
                record = JsonEncoder.decode(record_json)
                record = {k: record.get(k) for k in fields}
                record[REV] = int(_rev) - 1
                records[record[ID]] = record
        else:
            for record_json, _rev in zip(json_records, rev_strs):
                record = JsonEncoder.decode(record_json)
                record[REV] = int(_rev) - 1
                records[record[ID]] = record

        return records

    def fetch_all(self, fields: Set[Text] = None) -> Dict:
        return self.fetch_many(list(self.records.keys()), fields=fields)

    def upsert(self, record: Dict, pipe=None) -> Dict:
        is_creating = record.get(ID) is None
        _id = self.create_id(record)

        # prepare the record for upsert
        upserted_record = record.copy()
        upserted_record[ID] = _id

        # json encode and store record JSON
        self.records[_id] = self.encoder.encode(upserted_record)

        # update indexes
        for k, v in record.items():
            self.indexes[k].upsert(_id, v)

        # add rev to record AFTER insert to avoid storing _rev in records hset
        if is_creating:
            upserted_record[REV] = 0
        else:
            upserted_record[REV] = self.revs.increment(_id)

        return upserted_record

    def create(self, data: Dict) -> Dict:
        pipe = self.redis.pipeline()
        created_record = self.upsert(data)
        pipe.execute()
        return created_record

    def update(self, _id, record: Dict) -> Dict:
        pipe = self.redis.pipeline()
        updated_record = self.upsert(record, pipe=pipe)
        pipe.execute()
        return updated_record

    def create_many(self, records: List[Dict]) -> Dict:
        pipe = self.redis.pipeline()
        created_records = [self.upsert(rec, pipe=pipe) for rec in records]
        pipe.execute()
        return created_records

    def update_many(self, _ids: List, data: Dict = None) -> Dict:
        pipe = self.redis.pipeline()
        updated_records = [self.upsert(rec, pipe=pipe) for rec in records]
        pipe.execute()
        return updated_records

    def delete(self, _id) -> None:
        pipe = self.redis.pipeline()
        if self.records.delete(_id, pipe=pipe):
            for index in self.indexes.values():
                index.delete(_id, pipe=pipe)
        pipe.execute()

    def delete_many(self, _ids: List) -> None:
        pipe = self.redis.pipeline()
        if self.records.delete_many(_ids, pipe=pipe):
            self.revs.delete_many(_ids)
            for index in self.indexes.values():
                index.delete_many(_ids, pipe=pipe)
        pipe.execute()

    def delete_all(self):
        if self.count():
            self.delete_many(self.records.keys())

    def query(self, predicate: 'Predicate', **kwargs):
        if predicate is None:
            _ids = self.records.keys()
        else:
            _ids = self.query_ids(predicate)

        records = []

        if _ids:
            _id_field = self.resource_type.Schema.fields[ID]
            json_records = self.records.get_many(_ids)
            rev_strs = self.revs.get_many(_ids)
            for json_record, rev_str in zip(json_records, rev_strs):
                record = JsonEncoder.decode(json_record)
                record[REV] = int(rev_str.decode())
                records.append(record)

        return records

    def query_ids(self, predicate, pipeline=None):
        # TODO: use a redis pipeline object

        if isinstance(predicate, ConditionalPredicate):
            index = self.indexes.get(predicate.field.name)
            if index is None:
                # TODO: raise custom exception
                raise Exception('no index')

            ids = set()
            if predicate.op == OP_CODE.EQ:
                ids = set(index.search(
                    upper=predicate.value,
                    lower=predicate.value,
                    include_upper=True,
                    include_lower=True
                ))
            elif predicate.op == OP_CODE.NEQ:
                ids = set(index.search(
                    upper=predicate.value,
                    include_upper=False,
                    include_lower=True
                ))
                ids |= set(index.search(
                    lower=predicate.value,
                    include_upper=True,
                    include_lower=False
                ))
            elif predicate.op == OP_CODE.GEQ:
                ids = set(index.search(
                    lower=predicate.value,
                    include_lower=True
                ))
            elif predicate.op == OP_CODE.LEQ:
                ids = set(index.search(
                    upper=predicate.value,
                    include_upper=True
                ))
            elif predicate.op == OP_CODE.LT:
                ids = set(index.search(
                    upper=predicate.value,
                    include_upper=False
                ))
            elif predicate.op == OP_CODE.GT:
                ids = set(index.search(
                    lower=predicate.value,
                    include_lower=False
                ))
            elif predicate.op == OP_CODE.INCLUDING:
                ids = set()
                for v in predicate.value:
                    ids |= set(index.search(
                        upper=v,
                        lower=v,
                        include_upper=True,
                        include_lower=True
                    ))
            elif predicate.op == OP_CODE.EXCLUDING:
                ids = set()
                for v in predicate.value:
                    ids |= set(index.search(
                        upper=v,
                        include_upper=False,
                        include_lower=True
                    ))
                    ids |= set(index.search(
                        lower=v,
                        include_upper=True,
                        include_lower=False
                    ))
            else:
                raise ValueError('unrecognized op: {}'.format(predicate.op))
        elif isinstance(predicate, BooleanPredicate):
            ids_lhs = self.query_ids(predicate.lhs)
            if ids_lhs:
                ids_rhs = self.query_ids(predicate.rhs)
            else:
                ids_rhs = set()
            if predicate.op == OP_CODE.OR:
                ids = ids_lhs | ids_rhs
            elif predicate.op == OP_CODE.AND:
                ids = ids_lhs & ids_rhs
            else:
                raise ValueError('unrecognized op: {}'.format(predicate.op))

        return ids
示例#10
0
 def __init__(self, name, level=None, style=None):
     super().__init__(name, level=level)
     self._json = JsonEncoder()
     self._style = style or 'json'
示例#11
0
 def __init__(self, hostname: Text = None):
     self.hostname = (hostname or '').rstrip('/')
     self.json = JsonEncoder()
示例#12
0
class JsonSchemaGenerator:
    def __init__(self, hostname: Text = None):
        self.hostname = (hostname or '').rstrip('/')
        self.json = JsonEncoder()

    def from_schema(self, schema: 'Schema', encode=False) -> Dict:
        schema_class_name = self.get_schema_name(schema)
        json_schema = {
            '$schema': 'http://json-schema.org/schema#',
            '$id': f'{self.hostname}/schemas/{schema_class_name}.json',
            'properties': self._derive_properties(schema),
            'required': list(schema.required_fields.keys()),
        }
        if encode:
            return self.json.encode(json_schema)
        return json_schema

    def from_resource(self, resource_type: Type['Resource'], encode=False) -> Dict:
        json_schema = self.from_schema(resource_type.ravel.schema)
        for resolver in resource_type.ravel.resolvers.values():
            if resolver.private:
                continue
            if resolver.name not in resource_type.ravel.schema.fields:
                target_schema = resolver.target.ravel.schema
                field_dict = self._derive_property(target_schema)
                if resolver.many:
                    json_schema['properties'][resolver.name] = {
                        'type': 'array',
                        'default': [],
                        'items': field_dict
                    }
                else:
                    json_schema[resolver.name] = field_dict
        if encode:
            return self.json.encode(json_schema)
        return json_schema

    def _derive_properties(self, schema):
        properties = {}
        for field in schema.fields.values():
            if not field.meta.get('private', False):
                prop = self._derive_property(field)
                properties[field.name] = prop
        return properties

    def _derive_property(self, field: 'Field'):
        field_dict = {}
        if isinstance(field, field_types.String):
            field_dict['type'] = 'string'
            format_str = STRING_FIELD_TYPE_2_FORMAT.get(type(field))
            if format_str is not None:
                field_dict['format'] = format_str
        elif isinstance(field, field_types.Bool):
            field_dict['type'] = 'boolean'
        elif isinstance(field, field_types.Int):
            field_dict['type'] = 'integer'
        elif isinstance(field, field_types.Float):
            field_dict['type'] = 'number'
        elif isinstance(field, field_types.DateTime):
            field_dict['type'] = 'integer'
            field_dict['format'] = 'date-time'
        elif isinstance(field, field_types.DateTimeString):
            field_dict['type'] = 'string'
            field_dict['format'] = 'date-time'
        elif isinstance(field, field_types.Dict):
            field_dict['type'] = 'object'
        elif isinstance(field, (field_types.List, field_types.Set)):
            field_dict['type'] = 'array'
            field_dict['items'] = self._derive_property(field.nested)
            field_dict['default'] = []
        elif isinstance(field, field_types.Enum):
            inner_field_dict = self._derive_property(field.nested)
            field_dict['type'] = inner_field_dict['type']
            field_dict['enum'] = list(field.values)
        elif isinstance(field, Schema):
            defined_name = self.get_schema_name(field)
            field_dict['$ref'] = defined_name
        elif isinstance(field, field_types.Nested):
            defined_name = self.get_schema_name(field.schema_type)
            field_dict['$ref'] = defined_name
        elif isinstance(field, field_types.Uuid):
            field_dict['type'] = 'string'
            field_dict['format'] = 'uuid'
        else:
            field_dict['type'] = 'null'

        if field.nullable:
            field_dict['type'] = [field_dict['type'], 'null']

        return field_dict

    @staticmethod
    def get_schema_name(schema: 'Schema') -> Text:
        name = get_class_name(schema)
        if name.endswith('Schema'):
            name = name[:-6]
        return name
示例#13
0
 def __init__(self, json_encode=None, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.handler = type('Handler', (self.Handler, ), {'service': self})
     self.json_encode = json_encode or JsonEncoder().encode
     self.server = None
示例#14
0
from typing import Text, Type

import sqlalchemy as sa

from sqlalchemy import ForeignKey
from appyratus.utils.string_utils import StringUtils

from ravel.constants import REV, ID
from ravel.util.loggers import console
from ravel.util.json_encoder import JsonEncoder
from ravel.util.misc_functions import get_class_name
from ravel.schema import fields, Id

json_encoder = JsonEncoder()


class SqlalchemyTableBuilder(object):
    """
    The role of SqlalchemyTableBuilder is to derive and instantiate a
    Sqlalchemy Table object from a Resource object's schema. This process
    occurs in the Sqlalchemy's on_bootstrap method and assumes that the
    column names in the table map onto each schema's field.source attribute.
    """

    def __init__(self, store: 'SqlalchemyStore'):
        self._dialect = store.dialect
        self._resource_type = store.resource_type
        self._adapters = store.adapters
        self._metadata = store.get_metadata()

    @property
示例#15
0
文件: aes.py 项目: gigaquads/ravel
 def __init__(self, key: Text = None, iv: bytes = None):
     self.json = JsonEncoder()
     self.iv = iv or get_random_bytes(16)
     self.key = (key or random_uuid().hex).encode('utf-8')
示例#16
0
from __future__ import absolute_import

from ravel.util.json_encoder import JsonEncoder

from falcon import HTTPError, status_codes

json = JsonEncoder()


class RavelFalconError(HTTPError):

    http_status = status_codes.HTTP_400
    api_status = 'bad-request'
    default_message = 'bad request'

    def __init__(self, message=None, data=None):
        self.data = data or {}
        self.message = message or self.default_message
        super().__init__(status=self.http_status, description=self.message)

    def __repr__(self):
        return '<FalconError({})>'.format(self.__class__.__name__)

    def to_dict(self):
        return {
            'status': self.http_status,
            'message': self.message,
            'data': self.data,
        }

    def to_json(self):
示例#17
0
 def __init__(self, router=None, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self._json_encoder = JsonEncoder()
     self._route_2_resource = {}
     self._router = router