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
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
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
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)
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
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
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})'
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
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
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"))
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)
def derive_table_name(resource_type: Type['Resource']) -> Text: return StringUtils.snake(get_class_name(resource_type))
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
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
def store_class_name(self): return get_class_name(self)
def description(self) -> Text: return get_class_name(self)
def resource_type_name(self): return get_class_name(self.resource_type)
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()
def get_binding(self, resource_type): if isinstance(resource_type, type): resource_type = get_class_name(resource_type) return self._bindings.get(resource_type)