:py:mod:`magpie.adapter` ======================== .. py:module:: magpie.adapter Submodules ---------- .. toctree:: :titlesonly: :maxdepth: 1 magpieowssecurity/index.rst magpieservice/index.rst Package Contents ---------------- Classes ~~~~~~~ .. autoapisummary:: magpie.adapter.MagpieOWSSecurity magpie.adapter.MagpieServiceStore magpie.adapter.LooseVersion magpie.adapter.SingletonMeta magpie.adapter.MagpieAdapter magpie.adapter.HookContext Functions ~~~~~~~~~ .. autoapisummary:: magpie.adapter.evaluate_call magpie.adapter.raise_http magpie.adapter.valid_http magpie.adapter.verify_param magpie.adapter.get_request_info magpie.adapter.setup_magpie_configs magpie.adapter.get_constant magpie.adapter.get_auth_config magpie.adapter.get_cookies magpie.adapter.get_json magpie.adapter.get_logger magpie.adapter.get_magpie_url magpie.adapter.get_settings magpie.adapter.import_target magpie.adapter.is_json_body magpie.adapter.normalize_field_pattern magpie.adapter.setup_cache_settings magpie.adapter.setup_pyramid_config magpie.adapter.setup_session_config magpie.adapter.verify_user Attributes ~~~~~~~~~~ .. autoapisummary:: magpie.adapter.magpie_version magpie.adapter.SigninAPI magpie.adapter.CONTENT_TYPE_JSON magpie.adapter.LOGGER .. py:data:: magpie_version :value: '4.0.0' .. py:class:: MagpieOWSSecurity(container: magpie.typedefs.AnySettingsContainer) Bases: :py:obj:`twitcher.interface.OWSSecurityInterface` .. py:attribute:: _cached_request :type: Dict[uuid.UUID, pyramid.request.Request] .. py:method:: _get_service_cached(service_name: magpie.typedefs.Str, request_uuid: uuid.UUID) -> Tuple[magpie.services.ServiceInterface, Dict[str, magpie.typedefs.AnyValue]] Cache this method with :py:mod:`beaker` based on the provided caching key parameters. If the cache is not hit (expired timeout or new key entry), calls :func:`service_factory` to retrieve the actual :class:`ServiceInterface` implementation. Otherwise, returns the cached service to avoid SQL queries. .. note:: Function arguments are required to generate caching keys by which cached elements will be retrieved. Those arguments must be serializable to generate the cache key (i.e.: cannot pass a :class:`Request` object that contains session and other unserializable/circular references). .. seealso:: - :meth:`magpie.adapter.magpieowssecurity.MagpieOWSSecurity.get_service` - :meth:`magpie.adapter.magpieservice.MagpieServiceStore.fetch_by_name` .. py:method:: get_service(request: pyramid.request.Request) -> magpie.services.ServiceInterface Obtains the service referenced by the request. Caching is automatically handled according to configured application settings and whether the specific service name being requested was already processed recently and not expired. .. py:method:: verify_request(request: pyramid.request.Request) -> bool Verify that the service request is allowed. .. versionadded:: 3.18 Available only in ``Twitcher >= 0.6.x``. .. py:method:: check_request(request: pyramid.request.Request) -> None Verifies if the request user has access to the targeted resource according to parent service and permissions. If the request path corresponds to configured `Twitcher` proxy, evaluate the :term:`ACL`. Otherwise, ignore request access validation. In the case `Twitcher` proxy path is matched, the :term:`Logged User` **MUST** be allowed access following :term:`Effective Permissions ` resolution via :term:`ACL`. Otherwise, :exception:`OWSAccessForbidden` is raised. Failing to parse the request or any underlying component that raises an exception will be left up to the parent caller to handle the exception. In most typical use case, this means `Twitcher` will raise a generic :exception:`OWSException` with ``NoApplicableCode``, unless the exception was more specifically handled. :raises OWSAccessForbidden: If the user does not have access to the targeted resource under the service. :raises HTTPBadRequest: If a request parsing error was detected when trying to resolve the permission based on the service/resource. :raises Exception: Any derived exception that was not explicitly handled is re-raised directly after logging the event. :returns: Nothing if user has access. .. py:method:: update_request_cookies(request: pyramid.request.Request) -> None Ensure login of the user and update the request cookies if Twitcher is in a special configuration. Only update if ``MAGPIE_COOKIE_NAME`` is missing and is retrievable from ``access_token`` field within the ``Authorization`` header. Counter-validate the login procedure by calling Magpie's ``/session`` which should indicate if there is a logged user. .. py:class:: MagpieServiceStore(request: pyramid.request.Request) Bases: :py:obj:`twitcher.store.ServiceStoreInterface` Registry for OWS services. Uses magpie to fetch service url and attributes. .. py:method:: save_service(name: magpie.typedefs.Str, url: magpie.typedefs.Str, *args: Any, **kwargs: Any) -> NoReturn Store is read-only, use `Magpie` :term:`API` to add services. .. note:: Multiple redundant parameters are applied to support different `Twitcher` versions. - ``Twitcher <=0.5.x`` uses ``(service, *args, **kwargs)`` - ``Twitcher >=0.6.x`` uses ``(name, url, *args, **kwargs)`` - Some alternate interfaces also provided extra parameters at some point. .. py:method:: delete_service(name: magpie.typedefs.Str, *args: Any, **kwargs: Any) -> NoReturn Store is read-only, use :mod:`Magpie` :term:`API` to delete services. .. py:method:: list_services() -> List[twitcher.models.Service] Lists all services registered in `Magpie`. .. py:method:: _fetch_by_name_cached(service_name: magpie.typedefs.Str) -> twitcher.models.Service Cache this method with :py:mod:`beaker` based on the provided caching key parameters. If the cache is not hit (expired timeout or new key entry), calls :meth:`fetch_by_name` to retrieve the actual :class:`twitcher.datatype.Service` definition. Otherwise, returns the cached item to avoid SQL queries. .. note:: Function arguments are required to generate caching keys by which cached elements will be retrieved. .. note:: Method :meth:`fetch_by_name` gets triggered by :meth:`twitcher.owsproxy.owsproxy_view` after successful validation of granted access for :term:`Logged User` to the service / resources following call to :meth:`magpie.adapter.magpieowssecurity.MagpieOWSSecurity.check_request` in order to send and retrieve the actual response of that proxied service and forward it back to the requesting user. Caching helps greatly reduce recurrent SQL queries to convert `Twitcher` to `Magpie` service. .. seealso:: - :meth:`magpie.adapter.magpieowssecurity.MagpieOWSSecurity.get_service` - :meth:`magpie.adapter.magpieservice.MagpieServiceStore.fetch_by_name` .. py:method:: fetch_by_name(name: magpie.typedefs.Str) -> twitcher.models.Service Gets :class:`twitcher.datatype.Service` corresponding to :class:`magpie.models.Service` by ``name``. .. py:method:: fetch_by_url(url: magpie.typedefs.Str) -> twitcher.models.Service Gets service for given ``url`` from mongodb storage. .. py:method:: clear_services() -> NoReturn :abstractmethod: Magpie store is read-only, use magpie api to delete services. .. py:function:: evaluate_call(call: Callable[[], Any], fallback: Optional[Callable[[], None]] = None, http_error: Type[pyramid.httpexceptions.HTTPError] = HTTPInternalServerError, http_kwargs: Optional[magpie.typedefs.ParamsType] = None, msg_on_fail: magpie.typedefs.Str = '', content: Optional[magpie.typedefs.JSON] = None, content_type: magpie.typedefs.Str = CONTENT_TYPE_JSON, metadata: Optional[magpie.typedefs.JSON] = None) -> Any Evaluates the specified :paramref:`call` with a wrapped HTTP exception handling. On failure, tries to call. :paramref:`fallback` if specified, and finally raises the specified :paramref:`http_error`. Any potential error generated by :paramref:`fallback` or :paramref:`http_error` themselves are treated as :class:`HTTPInternalServerError`. Exceptions are generated using the standard output method formatted based on specified :paramref:`content_type`. Example: normal call:: try: res = func(args) except Exception as exc: fb_func() raise HTTPExcept(exc.message) wrapped call:: res = evaluate_call(lambda: func(args), fallback=lambda: fb_func(), http_error=HTTPExcept, **kwargs) :param call: function to call, *MUST* be specified as `lambda: ` :param fallback: function to call (if any) when `call` failed, *MUST* be `lambda: ` :param http_error: alternative exception to raise on `call` failure :param http_kwargs: additional keyword arguments to pass to `http_error` if called in case of HTTP exception :param msg_on_fail: message details to return in HTTP exception if `call` failed :param content: json formatted additional content to provide in case of exception :param content_type: format in which to return the exception (one of `magpie.common.SUPPORTED_ACCEPT_TYPES`) :param metadata: request metadata to add to the response body. (see: :func:`magpie.api.requests.get_request_info`) :raises http_error: on `call` failure :raises `HTTPInternalServerError`: on `fallback` failure :return: whichever return value `call` might have if no exception occurred .. py:function:: raise_http(http_error: Type[pyramid.httpexceptions.HTTPError] = HTTPInternalServerError, http_kwargs: Optional[magpie.typedefs.ParamsType] = None, detail: magpie.typedefs.Str = '', content: Optional[magpie.typedefs.JSON] = None, content_type: magpie.typedefs.Str = CONTENT_TYPE_JSON, metadata: Optional[magpie.typedefs.JSON] = None, nothrow: bool = False) -> NoReturn Raises error HTTP with standardized information formatted with content type. The content contains the corresponding http error code, the provided message as detail and optional specified additional json content (kwarg dict). .. seealso:: :func:`valid_http` for HTTP successful calls :param http_error: any derived class from base `HTTPError` (default: `HTTPInternalServerError`) :param http_kwargs: additional keyword arguments to pass to `http_error` if called in case of HTTP exception :param detail: additional message information (default: empty) :param content: JSON formatted content to include :param content_type: format in which to return the exception (one of `magpie.common.SUPPORTED_ACCEPT_TYPES`) :param metadata: request metadata to add to the response body. (see: :func:`magpie.api.requests.get_request_info`) :param nothrow: returns the error response instead of raising it automatically, but still handles execution errors :raises HTTPError: formatted raised exception with additional details and HTTP code :returns: HTTPError formatted exception with additional details and HTTP code only if `nothrow` is `True` .. py:function:: valid_http(http_success: Union[Type[pyramid.httpexceptions.HTTPSuccessful], Type[pyramid.httpexceptions.HTTPRedirection]] = HTTPOk, http_kwargs: Optional[magpie.typedefs.ParamsType] = None, detail: Optional[magpie.typedefs.Str] = '', content: Optional[magpie.typedefs.JSON] = None, content_type: Optional[magpie.typedefs.Str] = CONTENT_TYPE_JSON, metadata: Optional[magpie.typedefs.JSON] = None) -> Union[pyramid.httpexceptions.HTTPSuccessful, pyramid.httpexceptions.HTTPRedirection] Returns successful HTTP with standardized information formatted with content type. (see :func:`raise_http` for HTTP error calls) :param http_success: any derived class from *valid* HTTP codes (<400) (default: `HTTPOk`) :param http_kwargs: additional keyword arguments to pass to `http_success` when called :param detail: additional message information (default: empty) :param content: json formatted content to include :param content_type: format in which to return the exception (one of `magpie.common.SUPPORTED_ACCEPT_TYPES`) :param metadata: request metadata to add to the response body. (see: :func:`magpie.api.requests.get_request_info`) :returns: formatted successful response with additional details and HTTP code .. py:function:: verify_param(param: Any, param_compare: Optional[Union[Any, List[Any]]] = None, param_name: Optional[magpie.typedefs.Str] = None, param_content: Optional[magpie.typedefs.JSON] = None, with_param: bool = True, http_error: Type[pyramid.httpexceptions.HTTPError] = HTTPBadRequest, http_kwargs: Optional[magpie.typedefs.ParamsType] = None, msg_on_fail: magpie.typedefs.Str = '', content: Optional[magpie.typedefs.JSON] = None, content_type: magpie.typedefs.Str = CONTENT_TYPE_JSON, metadata: Optional[magpie.typedefs.JSON] = None, not_none: bool = False, not_empty: bool = False, not_in: bool = False, not_equal: bool = False, is_true: bool = False, is_false: bool = False, is_none: bool = False, is_empty: bool = False, is_in: bool = False, is_equal: bool = False, is_type: bool = False, matches: bool = False) -> None Evaluate various parameter combinations given the requested verification flags. Given a failing verification, directly raises the specified :paramref:`http_error`. Invalid usage exceptions generated by this verification process are treated as :class:`HTTPInternalServerError`. Exceptions are generated using the standard output method. :param param: parameter value to evaluate :param param_compare: Other value(s) to test :paramref:`param` against. Can be an iterable (single value resolved as iterable unless ``None``). To test for ``None`` type, use :paramref:`is_none`/:paramref:`not_none` flags instead. :param param_name: name of the tested parameter returned in response if specified for debugging purposes :param param_content: Additional JSON content to apply to generated error content on raise when :paramref:`with_param` is ``True``. Must be JSON serializable. Provided content can override generated error parameter if matching fields. :param with_param: On raise, adds values of :paramref:`param`, :paramref:`param_name` and :paramref:`param_compare`, as well as additional failing conditions metadata to the JSON response body for each of the corresponding value. :param http_error: derived exception to raise on test failure (default: :class:`HTTPBadRequest`) :param http_kwargs: additional keyword arguments to pass to :paramref:`http_error` called in case of HTTP exception :param msg_on_fail: message details to return in HTTP exception if flag condition failed :param content: json formatted additional content to provide in case of exception :param content_type: format in which to return the exception (one of :py:data:`magpie.common.SUPPORTED_ACCEPT_TYPES`) :param metadata: request metadata to add to the response body. (see: :func:`magpie.api.requests.get_request_info`) :param not_none: test that :paramref:`param` is not ``None`` type :param not_empty: test that :paramref:`param` is not an empty iterable (string, list, set, etc.) :param not_in: test that :paramref:`param` does not exist in :paramref:`param_compare` values :param not_equal: test that :paramref:`param` is not equal to :paramref:`param_compare` value :param is_true: test that :paramref:`param` is ``True`` :param is_false: test that :paramref:`param` is ``False`` :param is_none: test that :paramref:`param` is ``None`` type :param is_empty: test `param` for an empty iterable (string, list, set, etc.) :param is_in: test that :paramref:`param` exists in :paramref:`param_compare` values :param is_equal: test that :paramref:`param` equals :paramref:`param_compare` value :param is_type: test that :paramref:`param` is of same type as specified by :paramref:`param_compare` type :param matches: test that :paramref:`param` matches the regex specified by :paramref:`param_compare` value :raises HTTPError: if tests fail, specified exception is raised (default: :class:`HTTPBadRequest`) :raises HTTPInternalServerError: for evaluation error :return: nothing if all tests passed .. py:function:: get_request_info(request: Union[pyramid.request.Request, pyramid.httpexceptions.HTTPException], default_message: Optional[magpie.typedefs.Str] = None, exception_details: bool = False) -> magpie.typedefs.JSON Obtains additional content details about the :paramref:`request` according to available information. .. py:data:: SigninAPI .. py:function:: setup_magpie_configs(settings: magpie.typedefs.SettingsType, db_session: Optional[sqlalchemy.orm.session.Session] = None, setup_providers: bool = True, setup_permissions: bool = True, setup_webhooks: bool = True, skip_registration: bool = False) -> None Resolve known configuration file paths from settings or environment variables and process them for the application. .. seealso:: - https://pavics-magpie.readthedocs.io/en/latest/configuration.html#file-providers-cfg - https://pavics-magpie.readthedocs.io/en/latest/configuration.html#file-permissions-cfg - https://pavics-magpie.readthedocs.io/en/latest/configuration.html#configuration-file-formats - https://pavics-magpie.readthedocs.io/en/latest/configuration.html#combined-configuration-file .. py:class:: LooseVersion(version: str) Bases: :py:obj:`packaging.version.Version`, :py:obj:`VersionInterface` This class abstracts handling of a project's versions. A :class:`Version` instance is comparison aware and can be compared and sorted using the standard Python interfaces. >>> v1 = Version("1.0a5") >>> v2 = Version("1.0") >>> v1 >>> v2 >>> v1 < v2 True >>> v1 == v2 False >>> v1 > v2 False >>> v1 >= v2 False >>> v1 <= v2 True Initialize a Version object. :param version: The string representation of a version which will be parsed and normalized before use. :raises InvalidVersion: If the ``version`` does not conform to PEP 440 in any way then this exception will be raised. .. py:property:: version :type: Tuple[Union[int, str], Ellipsis] .. py:property:: patch .. py:method:: _cmp(other: Union[LooseVersion, str]) -> int .. py:function:: get_constant(constant_name: magpie.typedefs.Str, settings_container: Optional[magpie.typedefs.AnySettingsContainer] = None, settings_name: Optional[magpie.typedefs.Str] = None, default_value: Optional[magpie.typedefs.SettingValue] = None, raise_not_set: bool = True, raise_missing: bool = True, print_missing: bool = False, empty_missing: bool = False) -> magpie.typedefs.SettingValue Search in order for matched value of :paramref:`constant_name`: 1. search in :py:data:`MAGPIE_CONSTANTS` 2. search in settings if specified 3. search alternative setting names (see below) 4. search in :mod:`magpie.constants` definitions 5. search in environment variables Parameter :paramref:`constant_name` is expected to have the format ``MAGPIE_[VARIABLE_NAME]`` although any value can be passed to retrieve generic settings from all above mentioned search locations. If :paramref:`settings_name` is provided as alternative name, it is used as is to search for results if :paramref:`constant_name` was not found. Otherwise, ``magpie.[variable_name]`` is used for additional search when the format ``MAGPIE_[VARIABLE_NAME]`` was used for :paramref:`constant_name` (i.e.: ``MAGPIE_ADMIN_USER`` will also search for ``magpie.admin_user`` and so on for corresponding constants). :param constant_name: key to search for a value :param settings_container: WSGI application settings container (if not provided, uses found one in current thread) :param settings_name: alternative name for `settings` if specified :param default_value: default value to be returned if not found anywhere, and exception raises are disabled. :param raise_not_set: raise an exception if the found key is ``None``, search until last case if others are ``None`` :param raise_missing: raise exception if key is not found anywhere :param print_missing: print message if key is not found anywhere, return ``None`` :param empty_missing: consider an empty value for an existing key as if it was missing (i.e.: as if not set). :returns: found value or `default_value` :raises ValueError: if resulting value is invalid based on options (by default raise missing/empty/``None`` value) :raises LookupError: if no appropriate value could be found from all search locations (according to options) .. py:function:: get_auth_config(container: magpie.typedefs.AnySettingsContainer) -> pyramid.config.Configurator Generates Magpie application configuration with all utilities required for security and access control. .. py:data:: CONTENT_TYPE_JSON :value: 'application/json' .. py:class:: SingletonMeta Bases: :py:obj:`type` A metaclass that creates a Singleton base class when called. Create a class such that:: @six.add_metaclass(SingletonMeta) class A(object): pass @six.add_metaclass(SingletonMeta) class B(object): pass a1 = A() a2 = A() b1 = B() b2 = B() a1 is a2 # True b1 is b2 # True a1 is b1 # False .. py:attribute:: _instances .. py:method:: __call__(*args, **kwargs) Call self as a function. .. py:function:: get_cookies(request_or_response: Union[magpie.typedefs.AnyRequestType, magpie.typedefs.AnyResponseType]) -> magpie.typedefs.CookiesType Retrieves a dictionary of cookie names and values from distinct implementations and container types. :param request_or_response: Object that potentially contains cookies, by literal property or corresponding headers. :return: Found cookies. .. py:function:: get_json(request_or_response: Union[magpie.typedefs.AnyRequestType, magpie.typedefs.AnyResponseType]) -> magpie.typedefs.JSON Retrieves the 'JSON' body of a response using the property/callable according to the response's implementation. .. py:function:: get_logger(name: magpie.typedefs.Str, level: Optional[int] = None, force_stdout: bool = None, message_format: Optional[magpie.typedefs.Str] = None, datetime_format: Optional[magpie.typedefs.Str] = None) -> logging.Logger Immediately sets the logger level to avoid duplicate log outputs from the `root logger` and `this logger` when `level` is ``logging.NOTSET``. .. py:function:: get_magpie_url(container: Optional[magpie.typedefs.AnySettingsContainer] = None) -> magpie.typedefs.Str Obtains the configured Magpie URL entrypoint based on the various combinations of supported configuration settings. .. seealso:: Documentation section :ref:`config_app_settings` for available setting combinations. :param container: container that provides access to application settings. :return: resolved Magpie URL .. py:function:: get_settings(container: Optional[magpie.typedefs.AnySettingsContainer], app: bool = False) -> magpie.typedefs.SettingsType Retrieve application settings from a supported container. :param container: supported container with a handle to application settings. :param app: allow retrieving from current thread registry if no container was defined. :return: found application settings dictionary. :raise TypeError: when no application settings could be found or unsupported container. .. py:function:: import_target(target: magpie.typedefs.Str, default_root: Optional[magpie.typedefs.Str] = None) -> Optional[Any] Imports a target resource from a Python script as module. The Python script does not need to be defined within a module directory (i.e.: with ``__init__.py``). Files can be imported from virtually anywhere. To avoid name conflicts in generated module references, each imported target employs its full escaped file path as module name. Format expected as follows: .. code-block:: python "path/to/script.py:function" :param target: Resource to be imported. :param default_root: Root directory to employ if target is relative (default :data:`magpie.constants.MAGPIE_ROOT`). :return: Found and imported resource or None. .. py:function:: is_json_body(body: Any, return_body: bool = False) -> bool .. py:function:: normalize_field_pattern(pattern: magpie.typedefs.Str, escape: bool = True) -> magpie.typedefs.Str Escapes necessary regex pattern characters and applies start/end-of-line control characters. .. py:function:: setup_cache_settings(settings: magpie.typedefs.SettingsType, force: bool = False, enabled: bool = False, expire: int = 0) -> None Setup caching settings if not defined in configuration and enforce values if requested. Required caching regions that were missing from configuration are initiated with disabled caching by default. This ensures that any decorators or region references will not cause unknown key or region errors. :param settings: reference to application settings that will be updated in place. :param force: enforce following parameters, otherwise only ensure that caching regions exist. :param enabled: enable caching when enforced settings is requested. :param expire: cache expiration delay if setting values are enforced and enabled. .. py:function:: setup_pyramid_config(config: pyramid.config.Configurator) -> None Setup :mod:`Pyramid` utilities in the application configuration to define expected object references. .. py:function:: setup_session_config(config: pyramid.config.Configurator) -> None Setup database :class:`Session` transaction handlers and :class:`Request` properties for active :term:`User`. .. py:data:: LOGGER .. py:function:: verify_user(request: pyramid.request.Request) -> pyramid.httpexceptions.HTTPException Verifies that a valid user authentication on the pointed ``Magpie`` instance (via configuration) also results into a valid user authentication with the current ``Twitcher`` instance to ensure settings match between them. :param request: an HTTP request with valid authentication token/cookie credentials. :return: appropriate HTTP success or error response with details about the result. .. py:class:: MagpieAdapter(container: magpie.typedefs.AnySettingsContainer) Bases: :py:obj:`twitcher.adapter.base.AdapterInterface` .. py:property:: name :type: magpie.typedefs.Str .. py:method:: reset() -> None .. py:method:: describe_adapter() -> magpie.typedefs.JSON .. py:method:: servicestore_factory(request: pyramid.request.Request) -> magpieservice.MagpieServiceStore .. py:method:: tokenstore_factory(request: pyramid.request.Request) -> twitcher.store.AccessTokenStoreInterface :abstractmethod: Unused token store implementation. .. versionchanged:: 3.18 Available only in ``Twitcher <= 0.5.x``. .. py:method:: owsregistry_factory(request: pyramid.request.Request) -> twitcher.owsregistry.OWSRegistry Creates the :class:`OWSRegistry` implementation derived from :class:`MagpieServiceStore`. .. versionadded:: 3.18 Available only in ``Twitcher >= 0.6.x``. .. py:method:: owssecurity_factory(request: Optional[magpie.typedefs.AnySettingsContainer] = None) -> magpieowssecurity.MagpieOWSSecurity Creates the :class:`OWSSecurity` implementation derived from :class:`MagpieOWSSecurity`. .. versionchanged:: 3.18 Method :paramref:`request` does not exist starting in ``Twitcher >= 0.6.x``. .. py:method:: owsproxy_config(container: magpie.typedefs.AnySettingsContainer) -> None .. py:method:: configurator_factory(container: magpie.typedefs.AnySettingsContainer) -> pyramid.config.Configurator .. py:method:: _apply_hooks(instance: Union[pyramid.request.Request, pyramid.response.Response], service_name: magpie.typedefs.Str, hook_type: magpie.typedefs.ServiceHookType, method: magpie.typedefs.Str, path: magpie.typedefs.Str, query: magpie.typedefs.Str) -> Union[pyramid.request.Request, pyramid.response.Response] Executes the hooks processing chain. .. py:method:: _proxied_service_path(request: pyramid.request.Request) -> magpie.typedefs.Str :staticmethod: Extract the request extra path of the proxied service without :term:`Twitcher` proxy prefix. .. py:method:: request_hook(request: pyramid.request.Request, service: twitcher.models.service.ServiceConfig) -> pyramid.request.Request Apply modifications onto the request before sending it. .. versionadded:: 3.25 Requires ``Twitcher >= 0.7.x``. Request members employed after this hook is called include: - :meth:`Request.headers` - :meth:`Request.method` - :meth:`Request.body` This method can modified those members to adapt the request for specific service logic. .. py:method:: response_hook(response: pyramid.response.Response, service: twitcher.models.service.ServiceConfig) -> pyramid.response.Response Apply modifications onto the response from sent request. .. versionadded:: 3.25 Requires ``Twitcher >= 0.7.x``. The received response from the proxied service is normally returned directly. This method can modify the response to adapt it for specific service logic. .. py:method:: send_request(request: pyramid.request.Request, service: twitcher.models.service.ServiceConfig) -> pyramid.response.Response Send the request to the proxied service and handle its response. .. versionadded:: 3.31 Requires ``Twitcher >= 0.8.x``. Because requests are sometimes handled using :mod:`requests` depending on the service type, the ``request`` reference in the produced ``response`` is not always set. Ensure it is applied to allow :meth:`response_hook` retrieving it when attempting to resolve the proxied service path. .. py:class:: HookContext(instance: Union[pyramid.request.Request, pyramid.response.Response], adapter: MagpieAdapter, config: magpie.typedefs.ServiceConfigItem, hook: magpie.typedefs.ServiceHookConfigItem) Bases: :py:obj:`object` Context handlers associated to the request/response for the :term:`Service Hook` to be evaluated. Dispatch calls to database or other derived operations *on demand* as much as possible to minimize the impact of retrieving some parameters by each request that requires this hook context. .. py:property:: service :type: magpie.services.ServiceInterface Service implementation that defines the :term:`Resource` structure and :term:`Permission` resolution method. .. py:property:: resource :type: magpie.models.Resource Database :term:`Resource` that represents the :term:`Service` reference implementation. .. py:attribute:: adapter :type: MagpieAdapter .. py:attribute:: request :type: pyramid.request.Request .. py:attribute:: response :type: Optional[pyramid.response.Response] .. py:attribute:: config :type: magpie.typedefs.ServiceConfigItem .. py:attribute:: hook :type: magpie.typedefs.ServiceHookConfigItem .. py:attribute:: _service :type: Optional[magpie.services.ServiceInterface]