예제 #1
0
    def register(
        self,
        resource_type: Type['Resource'],
        store_type: Type['Store'],
        store_instance: 'Store' = None,
        store_bind_kwargs: Dict = None,
    ):
        store_class_name = get_class_name(store_type)
        if store_class_name not in self._named_store_types:
            store_type = type(store_class_name, (store_type, ), {})
            self._named_store_types[store_class_name] = store_type

        if store_instance is not None:
            assert isinstance(store_instance, store_type)
        else:
            store_instance = store_type()

        if resource_type is not None:
            resource_type_name = get_class_name(resource_type)
            resource_type.binder = self
            self._named_resource_types[resource_type_name] = resource_type
            self._bindings[resource_type_name] = binding = BizBinding(
                self,
                resource_type=resource_type,
                store_instance=store_instance,
                store_bind_kwargs=store_bind_kwargs,
            )
            return binding

        return None
예제 #2
0
파일: manifest.py 프로젝트: gigaquads/ravel
 def create_and_add_binding(resource_class, store_class):
     resource_class_name = get_class_name(resource_class)
     store_class_name = get_class_name(store_class)
     binding = Binding(resource_class_name, store_class_name)
     binding.resource_class = resource_class
     binding.store_class = store_class
     self.bindings.append(binding)
     return binding
예제 #3
0
파일: manifest.py 프로젝트: gigaquads/ravel
        def register_classes(resource_class, store_class):
            # add the resource class to global register if it's new
            resource_class_name = get_class_name(resource_class)
            if resource_class_name not in self.resource_classes:
                self.resource_classes[resource_class] = resource_class

            # add the store class to global register if it's new
            store_class_name = get_class_name(store_class)
            if store_class_name not in self.store_classes:
                self.store_classes[store_class_name] = store_class
예제 #4
0
파일: manifest.py 프로젝트: gigaquads/ravel
 def bootstrap_new_classes(resource_class, store_class):
     resource_class_name = get_class_name(resource_class)
     store_class_name = get_class_name(store_class)
     bootstraps = {x.store_class_name: x for x in self.bootstraps}
     if self.app.is_bootstrapped:
         bootstrap = self.bootstraps.get(store_class_name)
         params = bootstrap.params if bootstrap else {}
         if not store_class.is_bootstrapped():
             store_class.bootstrap(self.app, **params)
         if not resource_class.is_bootstraped():
             resource_class.bootstrap(self.app, **params)
예제 #5
0
    def get_store_instance(
        self,
        resource_type: Type['Resource'],
        bind=True,
        rebind=False,
    ) -> 'Store':
        if isinstance(resource_type, str):
            binding = self._bindings.get(resource_type)
        else:
            binding = self._bindings.get(get_class_name(resource_type))

        if binding is None:
            # lazily register a new binding
            base_store_type = resource_type.__store__()
            console.debug(
                f'calling {get_class_name(resource_type)}.__store__()')
            binding = self.register(resource_type, base_store_type)

        # call bind only if it already hasn't been called
        if rebind or ((not binding.is_bound) and bind):
            console.debug(message=(
                f'setting {get_class_name(binding.resource_type)}.ravel.store '
                f'= {get_class_name(binding.store_instance)}()'))
            binding.bind(binder=self)

        return binding.store_instance
예제 #6
0
 def __init__(self, guard, message=None, *args, **kwargs):
     super().__init__(message or 'guard failed', *args, **kwargs)
     self.guard = guard
     self.data['guard'] = {}
     self.data['guard']['class'] = get_class_name(guard)
     self.data['guard']['failed'] = guard.description
     if guard is not guard.root:
         self.data['guard']['description'] = guard.root.description
예제 #7
0
    def __str__(self):
        if self.prop:
            res_class_name = get_class_name(self.prop.resolver.owner)
            lhs = f'{res_class_name}.{self.prop.resolver.field.name}'
        else:
            lhs = '[NULL]'

        val = self.value

        return f'({lhs} {OP_CODE_2_DISPLAY_STRING[self.op]} {val})'
예제 #8
0
파일: action.py 프로젝트: gigaquads/ravel
    def to_dict(self):
        data = {
            'timestamp': self.timestamp.isoformat(),
            'message': self.exc_message,
            'traceback': self.trace,
        }

        if isinstance(self.exc, RavelError):
            if not self.exc.wrapped_exception:
                data['exception'] = get_class_name(self.exc)
            else:
                data['exception'] = get_class_name(self.exc.wrapped_exception)

            if self.exc.logged_traceback_depth is not None:
                depth = self.exc.logged_traceback_depth
                data['traceback'] = data['traceback'][-2 * depth:]

        if self.middleware is not None:
            data['middleware'] = get_class_name(self.middleware)

        if isinstance(self.exc, RavelError):
            data.update(self.exc.data)

        return data
예제 #9
0
    def bind(self, binder=None, force=False):
        if self._is_bound:
            if not force:
                console.warning(
                    message=('resource store binding already set. '
                             'skipping repeated bind call'),
                    data={'resource_type': get_class_name(self.resource_type)})
                return

        binder = binder or self.binder

        # associate a singleton Store instance with the res class.
        self.store_instance.bind(self.resource_type, **self.store_bind_kwargs)

        # first call bind on the Resource class itself
        self.resource_type.bind(binder)

        self._is_bound = True
예제 #10
0
파일: manifest.py 프로젝트: gigaquads/ravel
    def _bootstrap_app_actions(self):
        for action in self.app.actions.values():
            action.bootstrap()

        on_parts = []
        pre_parts = []
        post_parts = deque()

        def is_virtual(func):
            return getattr(func, 'is_virtual', None)

        # middleware bootstrapping...
        for idx, mware in enumerate(self.app.middleware):
            mware.bootstrap(app=self.app)

            # everything below is for generating the log message
            # containing the "action execution diagram"
            name = StringUtils.snake(get_class_name(mware))
            if not is_virtual(mware.pre_request):
                pre_parts.append(f"↪ {name}.pre_request(raw_args, raw_kwargs)")

            if not is_virtual(mware.on_request):
                on_parts.append(f"↪ {name}.on_request(args, kwargs)")
            if not is_virtual(mware.post_request):
                if is_virtual(mware.post_bad_request):
                    post_parts.appendleft(f"↪ {name}.post_request(result)")
                else:
                    post_parts.appendleft(
                        f"↪ {name}.post_[bad_]request(result|error)")
            elif not is_virtual(mware.post_bad_request):
                post_parts.appendleft(f"↪ {name}.post_bad_request(error)")

        parts = []
        parts.append('➥ app.on_request(action, *raw_args, **raw_kwargs)')
        parts.extend(pre_parts)
        parts.append('➥ args, kwargs = action.marshal(raw_args, raw_kwargs)')
        parts.extend(on_parts)
        parts.append('➥ raw_result = action(*args, **kwargs)')
        parts.extend(post_parts)
        parts.append('➥ return app.on_response(action, raw_result)')

        diagram = '\n'.join(f'{"  " * (i+1)}{s}' for i, s in enumerate(parts))
        console.debug(message=(f"action execution diagram...\n\n {diagram}\n"))
예제 #11
0
        def create_logger(level):
            """
            Setup root application logger.
            """
            if self.manifest.package:
                name = (
                    f'{self.manifest.package}:'
                    f'{os.getpid()}:'
                    f'{get_ident()}'
                )
            else:
                class_name = get_class_name(self)
                name = (
                    f'{StringUtils.snake(class_name)}:'
                    f'{os.getpid()}:'
                    f'{get_ident()}'
                )

            return ConsoleLoggerInterface(name, level)
예제 #12
0
 def derive_table_name(resource_type: Type['Resource']) -> Text:
     return StringUtils.snake(get_class_name(resource_type))
예제 #13
0
 def is_registered(self, resource_type: Type['Resource']) -> bool:
     if isinstance(resource_type, str):
         return resource_type in self._bindings
     else:
         return get_class_name(resource_type) in self._bindings
예제 #14
0
 def is_bound(self, resource_type: Type['Resource']) -> bool:
     if isinstance(resource_type, str):
         return self._bindings[resource_type].is_bound
     else:
         return self._bindings[get_class_name(resource_type)].is_bound
예제 #15
0
 def store_class_name(self):
     return get_class_name(self)
예제 #16
0
 def description(self) -> Text:
     return get_class_name(self)
예제 #17
0
 def resource_type_name(self):
     return get_class_name(self.resource_type)
예제 #18
0
    def emit(
        self,
        app: 'Application',
        schema_type: Type['Schema'],
        type_name: Text = None,
        depth=1,
        force=False,
    ) -> Text:
        """
        Recursively generate a protocol buffer message type declaration
        string from a given Schema class.
        """
        if isinstance(schema_type, (type, Schema)):
            type_name = get_stripped_schema_name(
                type_name or get_class_name(schema_type)
            )
        else:
            raise ValueError(
                'unrecognized schema type: "{}"'.format(schema_type)
            )

        # we don't want to create needless copies of to Resource schemas
        # while recursively generating nested message types.
        if (not force) and (type_name in app.manifest.resource_classes):
            return None

        prepared_data = []
        field_decls = []

        for f in schema_type.fields.values():
            # compute the "field number"
            field_no = f.meta.get('field_no', sys.maxsize)
            if field_no is None:
                raise ValueError(f'f has no protobuf field number')

            # get the field adapter
            adapter = self.get_adapter(f)
            if not adapter:
                raise Exception('no adapter for type {}'.format(type(f)))

            # store in intermediate data structure for purpose of sorting by
            # field numbers
            prepared_data.append((field_no, f, adapter))

        # emit field declarations in order of field number ASC
        sorted_data = sorted(prepared_data, key=lambda x: x[0])
        for (field_no, field, adapter) in sorted_data:
            field_decl = adapter.emit(field, field_no)
            field_decls.append(('  ' * depth) + field_decl + ';')

        nested_message_types = []
        for nested_schema in {type(s) for s in schema_type.children}:
            type_source = self.emit(
                app, nested_schema, depth=depth + 1, force=force
            )
            if type_source is not None:
                nested_message_types.append(type_source)

        MESSAGE_TYPE_FSTR = (
            (('   ' * (depth - 1)) + '''message {type_name} ''') + \
            ('''{{\n{nested_message_types}{field_lines}\n''') + \
            (('   ' * (depth - 1)) + '''}}''')
        )

        # emit the message declaration "message Foo { ... }"
        return MESSAGE_TYPE_FSTR.format(
            type_name=type_name,
            nested_message_types=(
                '\n'.join(nested_message_types) + '\n'
                if nested_message_types else ''
            ),
            field_lines='\n'.join(field_decls),
        ).rstrip()
예제 #19
0
 def get_binding(self, resource_type):
     if isinstance(resource_type, type):
         resource_type = get_class_name(resource_type)
     return self._bindings.get(resource_type)