def get_storage_factory(settings, prefix='filestore'): """Uses a Pyramid deployment settings dictionary to construct and return an instance of a :class:`FileStorage` subclass. The `prefix` will be used to extract storage configuration. The package to use is determined by the `$prefix` config setting, and any setting named `$prefix.$key` will be passed to the subclass constructor as `$key`. The `$prefix` config setting may be either the full dotted python name of a data manager class, or the name of one of the modules in the floof.model.filestore namespace, currently `local` or `mogilefs`. """ # Pull prefix.key out of the config object kwargs = {} plen = len(prefix) for key, val in settings.iteritems(): if key[0:plen] == prefix and len(key) > plen: kwargs[ key[plen+1:] ] = val # Resolve the data manager resolver = DottedNameResolver(None) manager = settings[prefix] name = 'floof.model.filestore.' + manager + '.FileStorage' try: storage = resolver.resolve(name) except ImportError: storage = resolver.resolve(manager) def storage_factory(): """Returns an instance of the chosen data manager for attachement to a request object and use over the life of a single request. The instance must be manually joined to a Zope-style transaction.""" return storage(transaction.manager, **kwargs) return storage_factory
def get_storage_factory(settings, prefix='filestore'): """Uses a Pyramid deployment settings dictionary to construct and return an instance of a :class:`FileStorage` subclass. The `prefix` will be used to extract storage configuration. The package to use is determined by the `$prefix` config setting, and any setting named `$prefix.$key` will be passed to the subclass constructor as `$key`. The `$prefix` config setting may be either the full dotted python name of a data manager class, or the name of one of the modules in the floof.model.filestore namespace, currently `local` or `mogilefs`. """ # Pull prefix.key out of the config object kwargs = {} plen = len(prefix) for key, val in settings.iteritems(): if key[0:plen] == prefix and len(key) > plen: kwargs[key[plen + 1:]] = val # Resolve the data manager resolver = DottedNameResolver(None) manager = settings[prefix] name = 'floof.model.filestore.' + manager + '.FileStorage' try: storage = resolver.resolve(name) except ImportError: storage = resolver.resolve(manager) def storage_factory(): """Returns an instance of the chosen data manager for attachement to a request object and use over the life of a single request. The instance must be manually joined to a Zope-style transaction.""" return storage(transaction.manager, **kwargs) return storage_factory
def disqus_comments_view(context, request): settings = get_settings_util() available = settings.get('kotti_disqus-disqus_available_types', []) available += get_settings()['kotti_disqus.extra_types'].split() resolver = DottedNameResolver(None) types = tuple(resolver.resolve(typ) for typ in available) if not isinstance(context, types): raise PredicateMismatch() api = template_api(context, request) disqus_url = '' disqus_shortname = settings['kotti_disqus-disqus_shortname'] base_url = settings['kotti_disqus-disqus_base_url'].strip('/') if base_url: disqus_url = base_url + api.url(context)[len(request.application_url):] else: disqus_url = api.url(context) return { 'disqus_shortname': disqus_shortname, 'disqus_url': disqus_url, }
def check_password(cls, **kwargs): if 'id' in kwargs: user = cls.get_by_id(kwargs['id']) if 'login' in kwargs: user = cls.get_by_login(kwargs['login']) if not user: return False try: if BCRYPTPasswordManager().check(user.password, '%s%s' % (kwargs['password'], user.salt)): return True except TypeError: pass request = get_current_request() fallback_auth = request.registry.settings.get('apex.fallback_auth') if fallback_auth: resolver = DottedNameResolver(fallback_auth.split('.', 1)[0]) fallback = resolver.resolve(fallback_auth) return fallback().check(DBSession, request, user, kwargs['password']) return False
def create_mailer(registry: Registry) -> IMailer: """Create a new mailer instance. """ settings = registry.settings # Empty values are not handled gracefully, so mutate them here before passing forward to mailer if settings.get("mail.username", "x") == "": settings["mail.username"] = None if settings.get("mail.password", "x") == "": settings["mail.password"] = None mailer_class = settings.get("websauna.mailer", "") if mailer_class in ("mail", ""): # TODO: Make mailer_class explicit so we can dynamically load pyramid_mail.Mailer # Default from pyramid_mailer import mailer_factory_from_settings mailer = mailer_factory_from_settings(settings) else: # debug backend resolver = DottedNameResolver() mailer_cls = resolver.resolve(mailer_class) mailer = mailer_cls() return mailer
def check_password(cls, **kwargs): user = None if 'id' in kwargs: user = cls.get_by_id(kwargs['id']) if 'login' in kwargs: user = cls.get_by_login(kwargs['login']) if not user: return False try: if bcrypt.checkpw(cls._pre_hash_password(kwargs['password']), user.password.encode('utf-8')): return True except TypeError: pass request = get_current_request() fallback_auth = request.registry.settings.get('apex.fallback_auth') if fallback_auth: resolver = DottedNameResolver(fallback_auth.split('.', 1)[0]) fallback = resolver.resolve(fallback_auth) return fallback().check(DBSession, request, user, kwargs['password']) return False
def _convert_component(self, component): """ Return the component class """ if inspect.isclass(component): return component else: resolver = DottedNameResolver() return resolver.resolve(component)
def get_profile(self, request=None): """ Returns AuthUser.profile object, creates record if it doesn't exist. .. code-block:: python from apex.models import AuthUser user = AuthUser.get_by_id(1) profile = user.get_profile(request) in **development.ini** .. code-block:: python apex.auth_profile = """ if not request: request = get_current_request() auth_profile = request.registry.settings.get('apex.auth_profile') if auth_profile: resolver = DottedNameResolver(auth_profile.split('.')[0]) profile_cls = resolver.resolve(auth_profile) return get_or_create(DBSession, profile_cls, auth_id=self.id)
def check_password(cls, **kwargs): if kwargs.has_key('id'): user = cls.get_by_id(kwargs['id']) if kwargs.has_key('login'): user = cls.get_by_login(kwargs['login']) request = get_current_request() use_sha256 = asbool(request.registry.settings.get('apex.use_sha256')) if not user: return False try: if use_sha256: pw = kwargs['password'] if CRYPTPasswordManager(SHA256CRYPT).check(user.password, pw): return True else: pw = kwargs['password'] + user.salt if BCRYPTPasswordManager().check(user.password, pw): return True except TypeError: pass fallback_auth = request.registry.settings.get('apex.fallback_auth') if fallback_auth: resolver = DottedNameResolver(fallback_auth.split('.', 1)[0]) fallback = resolver.resolve(fallback_auth) pw = kwargs['password'] return fallback().check(DBSession, request, user, pw) return False
def get_profile(self, request=None): """ Returns AuthUser.profile object, creates record if it doesn't exist. .. code-block:: python from apex.models import AuthUser user = AuthUser.get_by_id(1) profile = user.get_profile(request) in **development.ini** .. code-block:: python apex.auth_profile = """ if not request: request = get_current_request() auth_profile = request.registry.settings.get('apex.auth_profile') if auth_profile: resolver = DottedNameResolver(auth_profile.split('.')[0]) profile_cls = resolver.resolve(auth_profile) return get_or_create(DBSession, profile_cls, user_id=self.id)
def _parse_schedule(opt, val): resolver = DottedNameResolver() val = json.loads(val) for key, entry in val.items(): if isinstance(entry['schedule'], dict): schedule = resolver.resolve(entry['schedule']['factory'])( *entry['schedule'].get('args', ()), **entry['schedule'].get('kwargs', {})) else: schedule = float(entry['schedule']) entry['schedule'] = schedule return val
def includeme(config): resolver = DottedNameResolver() service_name = config.registry.settings.get("sms.service") if not service_name: raise SMSConfigurationError("sms.service setting missing") service_cls = resolver.resolve(service_name) if not service_cls: raise SMSConfigurationError("Not a valid sms.service: {}".format(service_name)) config.registry.registerAdapter(factory=service_cls, required=(IRequest,), provided=ISMSService)
def includeme(config): """ Pyramid entry point """ settings = config.registry.settings config.add_tween('rollbar.contrib.pyramid.rollbar_tween_factory', over=EXCVIEW) # run patch_debugtoolbar, unless they disabled it if asbool(settings.get('rollbar.patch_debugtoolbar', True)): patch_debugtoolbar(settings) def hook(request, data): data['framework'] = 'pyramid' if request: request.environ['rollbar.uuid'] = data['uuid'] if request.matched_route: data['context'] = request.matched_route.name rollbar.BASE_DATA_HOOK = hook kw = parse_settings(settings) access_token = kw.pop('access_token') environment = kw.pop('environment', 'production') if kw.get('scrub_fields'): kw['scrub_fields'] = set( [str.strip(x) for x in kw.get('scrub_fields').split('\n') if x]) if kw.get('exception_level_filters'): r = DottedNameResolver() exception_level_filters = [] for line in kw.get('exception_level_filters').split('\n'): if line: dotted_path, level = line.split() try: cls = r.resolve(dotted_path) exception_level_filters.append((cls, level)) except ImportError: log.error('Could not import %r' % dotted_path) kw['exception_level_filters'] = exception_level_filters kw['enabled'] = asbool(kw.get('enabled', True)) rollbar.init(access_token, environment, **kw)
def includeme(config): """ Pyramid entry point """ settings = config.registry.settings config.add_tween('rollbar.contrib.pyramid.rollbar_tween_factory', under=EXCVIEW) # run patch_debugtoolbar, unless they disabled it if asbool(settings.get('rollbar.patch_debugtoolbar', True)): patch_debugtoolbar(settings) def hook(request, data): data['framework'] = 'pyramid' if request: request.environ['rollbar.uuid'] = data['uuid'] if request.matched_route: data['context'] = request.matched_route.name rollbar.BASE_DATA_HOOK = hook kw = parse_settings(settings) access_token = kw.pop('access_token') environment = kw.pop('environment', 'production') if kw.get('scrub_fields'): kw['scrub_fields'] = set([str.strip(x) for x in kw.get('scrub_fields').split('\n') if x]) if kw.get('exception_level_filters'): r = DottedNameResolver() exception_level_filters = [] for line in kw.get('exception_level_filters').split('\n'): if line: dotted_path, level = line.split() try: cls = r.resolve(dotted_path) exception_level_filters.append((cls, level)) except ImportError: log.error('Could not import %r' % dotted_path) kw['exception_level_filters'] = exception_level_filters kw['enabled'] = asbool(kw.get('enabled', True)) rollbar.init(access_token, environment, **kw)
def includeme(config): resolver = DottedNameResolver() service_name = config.registry.settings.get("sms.service") if not service_name: raise SMSConfigurationError("sms.service setting missing") service_cls = resolver.resolve(service_name) if not service_cls: raise SMSConfigurationError( "Not a valid sms.service: {}".format(service_name)) config.registry.registerAdapter(factory=service_cls, required=(IRequest, ), provided=ISMSService)
def _find_methods(worker): cronjobsentry = worker.app.registry.settings.get('cronjobs') if cronjobsentry is None: raise ValueError("cronjobs must exist in application configuration if you want to run this. " "It should point to methods that can be run by the crontick worker. " "See voteit.core.scripts.crontick") resolver = DottedNameResolver(None) dotteds = [x.strip() for x in cronjobsentry.strip().splitlines()] methods = [] for dotted in dotteds: try: methods.append(resolver.resolve(dotted)) except ImportError, e: worker.logger.exception(e)
def _find_methods(worker): cronjobsentry = worker.app.registry.settings.get('cronjobs') if cronjobsentry is None: raise ValueError( "cronjobs must exist in application configuration if you want to run this. " "It should point to methods that can be run by the crontick worker. " "See voteit.core.scripts.crontick") resolver = DottedNameResolver(None) dotteds = [x.strip() for x in cronjobsentry.strip().splitlines()] methods = [] for dotted in dotteds: try: methods.append(resolver.resolve(dotted)) except ImportError, e: worker.logger.exception(e)
def check_password(cls, **kwargs): if kwargs.has_key("id"): user = cls.get_by_id(kwargs["id"]) if kwargs.has_key("login"): user = cls.get_by_login(kwargs["login"]) if not user: return False try: if BCRYPTPasswordManager().check(user.password, "%s%s" % (kwargs["password"], user.salt)): return True except TypeError: pass request = get_current_request() fallback_auth = request.registry.settings.get("apex.fallback_auth") if fallback_auth: resolver = DottedNameResolver(fallback_auth.split(".", 1)[0]) fallback = resolver.resolve(fallback_auth) return fallback().check(DBSession, request, user, kwargs["password"]) return False
def check_password(cls, **kwargs): if kwargs.has_key('id'): user = cls.get_by_id(kwargs['id']) if kwargs.has_key('login'): user = cls.get_by_login(kwargs['login']) if not user: return False try: if BCRYPTPasswordManager().check(user.password, '%s%s' % (kwargs['password'], user.salt)): return True except TypeError: pass request = get_current_request() fallback_auth = request.registry.settings.get('apex.fallback_auth') if fallback_auth: resolver = DottedNameResolver(fallback_auth.split('.', 1)[0]) fallback = resolver.resolve(fallback_auth) return fallback().check(DBSession, request, user, \ kwargs['password']) return False
def get_module(package): """ Returns a module based on the string passed """ resolver = DottedNameResolver(package.split('.', 1)[0]) return resolver.resolve(package)
class AppUser: """:class:`webtest.TestApp` wrapper for backend functional testing.""" def __init__(self, app_router: Router, rest_url: str='http://localhost', base_path: str='/', header: dict=None, user_path: str='', user_login: str='', user_password: str='', ): """Initialize self.""" self.app_router = app_router """The adhocracy wsgi application""" self.app = TestApp(app_router) """:class:`webtest.TestApp`to send requests to the backend server.""" self.rest_url = rest_url """backend server url to generate request urls.""" self.base_path = base_path """path prefix to generate request urls.""" self.header = header or {} """default header for requests, mostly for authentication. If not set, `user_login` and `user_password` is used to login, the new authentication header is stored in `header`. """ if user_password and user_login and not header: token, user_path = self._get_token_and_user_path(user_login, user_password) self.header = {UserTokenHeader: token} self.user_password = user_password """password for authenticated user.""" self.user_login = user_login """login name for authenticated user.""" self.user_path = user_path """path for authenticated user.""" self._resolver = DottedNameResolver() def _get_token_and_user_path(self, login: str, password: str) -> tuple: login_page = self.rest_url + '/login_username' data = {'name': login, 'password': password} resp = self.app.post_json(login_page, data).json return resp['user_token'], resp['user_path'] def post_resource(self, path: str, iresource: IInterface, cstruct: dict) -> TestResponse: """Build and post request to create a new resource.""" url = self._build_url(path) props = self._build_post_body(iresource, cstruct) resp = self.app.post_json(url, props, headers=self.header, expect_errors=True) return resp def put(self, path: str, cstruct: dict={}, upload_files: [(str, str, bytes)]=None, ) -> TestResponse: """Put request to modify a resource.""" url = self._build_url(path) kwargs = {'headers': self.header, 'expect_errors': True, } if upload_files: kwargs['upload_files'] = upload_files resp = self.app.put(url, cstruct, **kwargs) else: resp = self.app.put_json(url, cstruct, **kwargs) return resp def post(self, path: str, cstruct: dict={}, upload_files: [(str, str, bytes)]=None, ) -> TestResponse: """Post request to create a new resource.""" url = self._build_url(path) kwargs = {'headers': self.header, 'expect_errors': True, } if upload_files: kwargs['upload_files'] = upload_files resp = self.app.post(url, cstruct, **kwargs) else: resp = self.app.post_json(url, cstruct, **kwargs) return resp def _build_post_body(self, iresource: IInterface, cstruct: dict) -> dict: return {'content_type': iresource.__identifier__, 'data': cstruct} def _build_url(self, path: str) -> str: if path.startswith('http'): return path return self.rest_url + self.base_path + path def batch(self, subrequests: list): """Build and post batch request to the backend rest server.""" resp = self.app.post_json(batch_url, subrequests, headers=self.header, expect_errors=True) return resp def get(self, path: str, params={}) -> TestResponse: """Send get request to the backend rest server.""" url = self._build_url(path) resp = self.app.get(url, headers=self.header, params=params, expect_errors=True) return resp def delete(self, path: str) -> TestResponse: """Send delete request to the backend rest server.""" url = self._build_url(path) resp = self.app.delete(url, headers=self.header, expect_errors=True) return resp def options(self, path: str) -> TestResponse: """Send options request to the backend rest server.""" url = self._build_url(path) resp = self.app.options(url, headers=self.header, expect_errors=True) return resp def get_postable_types(self, path: str) -> []: """Send options request and return the postable content types.""" resp = self.options(path) if 'POST' not in resp.json: return [] post_request_body = resp.json['POST']['request_body'] type_names = sorted([r['content_type'] for r in post_request_body]) iresources = [self._resolver.resolve(t) for t in type_names] return iresources
class AppUser: """:class:`webtest.TestApp` wrapper for backend functional testing.""" def __init__( self, app_router: Router, base_path: str = '/', header: dict = None, user_path: str = '', user_login: str = '', user_password: str = '', ): """Initialize self.""" self.app_router = app_router """The adhocracy wsgi application""" self.app = TestApp(app_router) """:class:`webtest.TestApp`to send requests to the backend server.""" self.rest_url = rest_url() """backend server url to generate request urls.""" self.base_path = base_path """path prefix to generate request urls.""" self.header = header or {} """default header for requests, mostly for authentication. If not set, `user_login` and `user_password` is used to login, the new authentication header is stored in `header`. """ if user_password and user_login and not header: token, user_path = self._get_token_and_user_path( user_login, user_password) self.header = {UserTokenHeader: token} self.user_password = user_password """password for authenticated user.""" self.user_login = user_login """login name for authenticated user.""" self.user_path = user_path """path for authenticated user.""" self._resolver = DottedNameResolver() def _get_token_and_user_path(self, login: str, password: str) -> tuple: login_page = self.rest_url + '/login_username' data = {'name': login, 'password': password} resp = self.app.post_json(login_page, data).json return resp['user_token'], resp['user_path'] def post_resource(self, path: str, iresource: IInterface, cstruct: dict) -> TestResponse: """Build and post request to create a new resource.""" url = self._build_url(path) props = self._build_post_body(iresource, cstruct) resp = self.app.post_json(url, props, headers=self.header, expect_errors=True) return resp def put( self, path: str, cstruct: dict = {}, upload_files: [(str, str, bytes)] = None, extra_headers: dict = {}, ) -> TestResponse: """Put request to modify a resource.""" url = self._build_url(path) headers = copy(self.header) headers.update(extra_headers) kwargs = { 'headers': headers, 'expect_errors': True, } if upload_files: kwargs['upload_files'] = upload_files resp = self.app.put(url, cstruct, **kwargs) else: resp = self.app.put_json(url, cstruct, **kwargs) return resp def post( self, path: str, cstruct: dict = {}, upload_files: [(str, str, bytes)] = None, extra_headers: dict = {}, ) -> TestResponse: """Post request to create a new resource.""" url = self._build_url(path) headers = copy(self.header) headers.update(extra_headers) kwargs = { 'headers': headers, 'expect_errors': True, } if upload_files: kwargs['upload_files'] = upload_files resp = self.app.post(url, cstruct, **kwargs) else: resp = self.app.post_json(url, cstruct, **kwargs) return resp def _build_post_body(self, iresource: IInterface, cstruct: dict) -> dict: return {'content_type': iresource.__identifier__, 'data': cstruct} def _build_url(self, path: str) -> str: if path.startswith('http'): return path elif path.startswith('/') and (self.base_path == '\\'): return self.rest_url + path else: return self.rest_url + self.base_path + path def batch(self, subrequests: list): """Build and post batch request to the backend rest server.""" resp = self.app.post_json(batch_url, subrequests, headers=self.header, expect_errors=True) return resp def head(self, path: str, extra_headers={}) -> TestResponse: """Send head request to the backend rest server.""" url = self._build_url(path) headers = copy(self.header) headers.update(extra_headers) resp = self.app.head(url, headers=headers, expect_errors=True) return resp def get(self, path: str, params={}, extra_headers={}) -> TestResponse: """Send get request to the backend rest server.""" url = self._build_url(path) headers = copy(self.header) headers.update(extra_headers) resp = self.app.get(url, headers=headers, params=params, expect_errors=True) return resp def delete(self, path: str) -> TestResponse: """Send delete request to the backend rest server.""" url = self._build_url(path) resp = self.app.delete(url, headers=self.header, expect_errors=True) return resp def options(self, path: str) -> TestResponse: """Send options request to the backend rest server.""" url = self._build_url(path) resp = self.app.options(url, headers=self.header, expect_errors=True) return resp def get_postable_types(self, path: str) -> []: """Send options request and return the postable content types.""" resp = self.options(path) if 'POST' not in resp.json: return [] post_request_body = resp.json['POST']['request_body'] type_names = sorted([r['content_type'] for r in post_request_body]) iresources = [self._resolver.resolve(t) for t in type_names] return iresources
class AppUser: """:class:`webtest.TestApp` wrapper for backend functional testing.""" def __init__(self, app, rest_url: str = 'http://localhost', base_path: str = '/', header: dict = None): """Initialize self.""" self.app = TestApp(app) """:class:`webtest.TestApp`to send requests to the backend server.""" self.rest_url = rest_url """backend server url to generate request urls.""" self.base_path = base_path """path prefix to generate request urls.""" self.header = header or {} """default header for requests, mostly for authentication.""" self._resolver = DottedNameResolver() def post_resource(self, path: str, iresource: IInterface, cstruct: dict) -> TestResponse: """Build and post request to create a new resource.""" url = self._build_url(path) props = self._build_post_body(iresource, cstruct) resp = self.app.post_json(url, props, headers=self.header, expect_errors=True) return resp def put(self, path: str, cstruct: dict = {}) -> TestResponse: """Put request to modify a resource.""" url = self._build_url(path) resp = self.app.put_json(url, cstruct, headers=self.header, expect_errors=True) return resp def post(self, path: str, cstruct: dict = {}) -> TestResponse: """Post request to create a new resource.""" url = self._build_url(path) resp = self.app.post_json(url, cstruct, headers=self.header, expect_errors=True) return resp def _build_post_body(self, iresource: IInterface, cstruct: dict) -> dict: return {'content_type': iresource.__identifier__, 'data': cstruct} def _build_url(self, path: str) -> str: if path.startswith('http'): return path return self.rest_url + self.base_path + path def batch(self, subrequests: list): """Build and post batch request to the backend rest server.""" resp = self.app.post_json(batch_url, subrequests, headers=self.header, expect_errors=True) return resp def get(self, path: str, params={}) -> TestResponse: """Send get request to the backend rest server.""" url = self._build_url(path) resp = self.app.get(url, headers=self.header, params=params, expect_errors=True) return resp def options(self, path: str) -> TestResponse: """Send options request to the backend rest server.""" url = self._build_url(path) resp = self.app.options(url, headers=self.header, expect_errors=True) return resp def get_postable_types(self, path: str) -> []: """Send options request and return the postable content types.""" resp = self.options(path) if 'POST' not in resp.json: return [] post_request_body = resp.json['POST']['request_body'] type_names = sorted([r['content_type'] for r in post_request_body]) iresources = [self._resolver.resolve(t) for t in type_names] return iresources
def get_imperative_config(package): resolver = DottedNameResolver(package) try: return resolver.resolve('.application:configure_karl') except ImportError: return None
class AppUser: """:class:`webtest.TestApp` wrapper for backend functional testing.""" def __init__(self, app, rest_url: str='http://localhost', base_path: str='/', header: dict=None): """Initialize self.""" self.app = TestApp(app) """:class:`webtest.TestApp`to send requests to the backend server.""" self.rest_url = rest_url """backend server url to generate request urls.""" self.base_path = base_path """path prefix to generate request urls.""" self.header = header or {} """default header for requests, mostly for authentication.""" self._resolver = DottedNameResolver() def post_resource(self, path: str, iresource: IInterface, cstruct: dict) -> TestResponse: """Build and post request to create a new resource.""" url = self._build_url(path) props = self._build_post_body(iresource, cstruct) resp = self.app.post_json(url, props, headers=self.header, expect_errors=True) return resp def put(self, path: str, cstruct: dict={}) -> TestResponse: """Put request to modify a resource.""" url = self._build_url(path) resp = self.app.put_json(url, cstruct, headers=self.header, expect_errors=True) return resp def post(self, path: str, cstruct: dict={}) -> TestResponse: """Post request to create a new resource.""" url = self._build_url(path) resp = self.app.post_json(url, cstruct, headers=self.header, expect_errors=True) return resp def _build_post_body(self, iresource: IInterface, cstruct: dict) -> dict: return {'content_type': iresource.__identifier__, 'data': cstruct} def _build_url(self, path: str) -> str: if path.startswith('http'): return path return self.rest_url + self.base_path + path def batch(self, subrequests: list): """Build and post batch request to the backend rest server.""" resp = self.app.post_json(batch_url, subrequests, headers=self.header, expect_errors=True) return resp def get(self, path: str, params={}) -> TestResponse: """Send get request to the backend rest server.""" url = self._build_url(path) resp = self.app.get(url, headers=self.header, params=params, expect_errors=True) return resp def options(self, path: str) -> TestResponse: """Send options request to the backend rest server.""" url = self._build_url(path) resp = self.app.options(url, headers=self.header, expect_errors=True) return resp def get_postable_types(self, path: str) -> []: """Send options request and return the postable content types.""" resp = self.options(path) if 'POST' not in resp.json: return [] post_request_body = resp.json['POST']['request_body'] type_names = sorted([r['content_type'] for r in post_request_body]) iresources = [self._resolver.resolve(t) for t in type_names] return iresources