class _View(self.config.get('base', Service)): __allow_access__ = self.config.get('allow_access', False) __route__ = routes.Route(self.config.get('name', '')) view_func = staticmethod(func) async def __call__(self): return await func(self.context, self.request)
def __call__(self, func): self.config["module"] = func if isinstance(func, type): if not hasattr(func, "__call__"): raise ServiceConfigurationError( f"Service must have async def __call__ method: {func.__call__}\n" f"{pformat(self.config)}") if not asyncio.iscoroutinefunction(func.__call__): raise ServiceConfigurationError( f"Service __call__ method must be async: {func.__call__}\n" f"{pformat(self.config)}") klass = func original = klass.__call__ call_original = klass._call_original else: if not _has_parameters(func): raise ServiceConfigurationError( f"Service configuration must accept 2 required parameters: {func}\n" f"{pformat(self.config)}") if not asyncio.iscoroutinefunction(func): raise ServiceConfigurationError( f"Service function must be async: {func}\n" f"{pformat(self.config)}") from guillotina.api.service import Service klass = self.config.get("base", Service) original = staticmethod(func) call_original = klass._call_original_func call = call_original if self.config.get("validate", False): call = klass._call_validate # create new class with customizations klass = type( func.__name__, (klass, ), { **dict(klass.__dict__), **{ "__module__": func.__module__, "__allow_access__": self.config.get("allow_access", getattr(klass, "__allow_access__", False)), "__route__": routes.Route(self.config.get("name", "")), "__config__": self.config, "__original__": original, "__call__": call, "_call_original": call_original, }, }, ) register_configuration(klass, self.config, "service") return func
def load_service(_context, service): # prevent circular import from guillotina.security.utils import protect_view service_conf = service["config"] factory = resolve_dotted_name(service["klass"]) permission = service_conf.get("permission", app_settings.get("default_permission", None)) protect_view(factory, permission) method = service_conf.get("method", "GET") default_layer = resolve_dotted_name( app_settings.get("default_layer", IDefaultLayer)) layer = service_conf.get("layer", default_layer) name = service_conf.get("name", "") content = service_conf.get("context", Interface) logger.debug("Defining adapter for " # noqa "{0:s} {1:s} {2:s} to {3:s} name {4:s}".format( content.__identifier__, app_settings["http_methods"][method].__identifier__, layer.__identifier__, str(factory), name, )) if not getattr(factory, "__route__", None): factory.__route__ = routes.Route(name) else: factory.__route__.service_configuration = service_conf service_conf["route"] = [str(rp) for rp in factory.__route__.route_parts] component.adapter( _context, factory=(factory, ), provides=app_settings["http_methods"][method], for_=(content, layer), name=factory.__route__.view_name, ) api = app_settings["api_definition"] ct_name = content.__identifier__ if ct_name not in api: api[ct_name] = OrderedDict() ct_api = api[ct_name] if name: if "endpoints" not in ct_api: ct_api["endpoints"] = OrderedDict() if name not in ct_api["endpoints"]: ct_api["endpoints"][name] = OrderedDict() ct_api["endpoints"][name][method] = OrderedDict(service_conf) else: ct_api[method] = OrderedDict(service_conf)
def load_service(_context, service): # prevent circular import from guillotina.security.utils import protect_view service_conf = service['config'] factory = resolve_dotted_name(service['klass']) permission = service_conf.get( 'permission', app_settings.get('default_permission', None)) protect_view(factory, permission) method = service_conf.get('method', 'GET') default_layer = resolve_dotted_name( app_settings.get('default_layer', IDefaultLayer)) layer = service_conf.get('layer', default_layer) name = service_conf.get('name', '') content = service_conf.get('context', Interface) logger.debug('Defining adapter for ' # noqa '{0:s} {1:s} {2:s} to {3:s} name {4:s}'.format( content.__identifier__, app_settings['http_methods'][method].__identifier__, layer.__identifier__, str(factory), name)) if not getattr(factory, '__route__', None): factory.__route__ = routes.Route(name) else: factory.__route__.service_configuration = service_conf component.adapter( _context, factory=(factory,), provides=app_settings['http_methods'][method], for_=(content, layer), name=factory.__route__.view_name ) api = app_settings['api_definition'] ct_name = content.__identifier__ if ct_name not in api: api[ct_name] = OrderedDict() ct_api = api[ct_name] if name: if 'endpoints' not in ct_api: ct_api['endpoints'] = OrderedDict() if name not in ct_api['endpoints']: ct_api['endpoints'][name] = OrderedDict() ct_api['endpoints'][name][method] = OrderedDict(service_conf) else: ct_api[method] = OrderedDict(service_conf)
def __call__(self, func): self.config['module'] = func if isinstance(func, type): if not hasattr(func, '__call__'): raise ServiceConfigurationError( f'Service must have async def __call__ method: {func.__call__}\n' f'{pformat(self.config)}' ) if not asyncio.iscoroutinefunction(func.__call__): raise ServiceConfigurationError( f'Service __call__ method must be async: {func.__call__}\n' f'{pformat(self.config)}' ) # create new class with customizations klass = type(func.__name__, (func,), dict(func.__dict__)) klass.__module__ = func.__module__ klass.__allow_access__ = self.config.get( 'allow_access', getattr(func, '__allow_access__', False)) klass.__route__ = routes.Route(self.config.get('name', '')) register_configuration(klass, self.config, 'service') else: if not _has_parameters(func): raise ServiceConfigurationError( f'Service configuration must accept 2 required parameters: {func}\n' f'{pformat(self.config)}') if not asyncio.iscoroutinefunction(func): raise ServiceConfigurationError( f'Service function must be async: {func}\n' f'{pformat(self.config)}' ) # avoid circular imports from guillotina.api.service import Service class _View(self.config.get('base', Service)): __allow_access__ = self.config.get('allow_access', False) __route__ = routes.Route(self.config.get('name', '')) view_func = staticmethod(func) async def __call__(self): return await func(self.context, self.request) register_configuration(_View, self.config, 'service') return func
class _View(func): __allow_access__ = self.config.get( 'allow_access', getattr(func, '__allow_access__', False)) __route__ = routes.Route(self.config.get('name', ''))
def test_convert_simple_route_to_view_name(): assert routes.Route("@foobar").view_name == "@foobar"
def test_convert_path_route_to_view_name(): assert routes.Route("@foobar/{p:path}").view_name == "@foobar?"
def test_convert_non_routing_to_view_name(): assert routes.Route('foo/bar').view_name == 'foo/bar'
def test_convert_route_to_view_name(): assert routes.Route("@foobar/{foo}/{bar}").view_name == "@foobar//" assert routes.Route("@foobar/foobar/{foo}/{bar}").view_name == "@foobar///"
def test_convert_non_routing_to_view_name_mix(): assert routes.Route("foo/{bar}").view_name == "foo/"
def test_convert_non_routing_to_view_name(): assert routes.Route("foo/bar").view_name == "foo/"
def test_convert_simple_route_to_view_name(): assert routes.Route('@foobar').view_name == '@foobar'
def test_throws_error_for_invalid_route(): with pytest.raises(InvalidRoute): routes.Route('@foobar/foobar/{foo}/{bar}')
def test_convert_route_to_view_name(): assert routes.Route('@foobar/{foo}/{bar}').view_name == '@foobar//'
def test_invalid_non_route(): with pytest.raises(InvalidRoute): routes.Route("{foobar}/{foo}/{bar}")
def test_convert_non_routing_to_view_name_mix(): assert routes.Route('foo/{bar}').view_name == 'foo/'