Module dexa_sdk.agent.config.injection_context

Injection context implementation.

Expand source code
"""Injection context implementation."""

from collections import namedtuple
import copy
import logging
from typing import Mapping

from ..config.injector import Injector
from aries_cloudagent.config.base import BaseInjector, InjectorError
from aries_cloudagent.config.settings import Settings

Scope = namedtuple("Scope", "name injector")
LOGGER = logging.getLogger(__name__)


class InjectionContextError(InjectorError):
    """Base class for issues in the injection context."""


class InjectionContext(BaseInjector):
    """Manager for configuration settings and class providers."""

    ROOT_SCOPE = "application"

    def __init__(
        self, *, settings: Mapping[str, object] = None, enforce_typing: bool = True
    ):
        """Initialize a `ServiceConfig`."""
        self._injector = Injector(settings, enforce_typing=enforce_typing)
        self._scope_name = InjectionContext.ROOT_SCOPE
        self._scopes = []

    @property
    def injector(self) -> Injector:
        """Accessor for scope-specific injector."""
        return self._injector

    @injector.setter
    def injector(self, injector: Injector):
        """Setter for scope-specific injector."""
        self._injector = injector

    @property
    def scope_name(self) -> str:
        """Accessor for the current scope name."""
        return self._scope_name

    @scope_name.setter
    def scope_name(self, scope_name: str):
        """Accessor for the current scope name."""
        self._scope_name = scope_name

    @property
    def settings(self) -> Settings:
        """Accessor for scope-specific settings."""
        return self.injector.settings

    @settings.setter
    def settings(self, settings: Settings):
        """Setter for scope-specific settings."""
        self.injector.settings = settings

    def update_settings(self, settings: Mapping[str, object]):
        """Update the scope with additional settings."""
        if settings:
            self.injector.settings = self.injector.settings.extend(settings)

    def start_scope(
        self, scope_name: str, settings: Mapping[str, object] = None
    ) -> "InjectionContext":
        """Begin a new named scope.

        Args:
            scope_name: The unique name for the scope being entered
            settings: An optional mapping of additional settings to apply

        Returns:
            A new injection context representing the scope

        """
        if not scope_name:
            raise InjectionContextError("Scope name must be non-empty")
        if self.scope_name == scope_name:
            raise InjectionContextError(
                "Cannot re-enter scope: {}".format(scope_name))
        for scope in self._scopes:
            if scope.name == scope_name:
                raise InjectionContextError(
                    "Cannot re-enter scope: {}".format(scope_name)
                )
        result = self.copy()
        result._scopes.append(
            Scope(name=self.scope_name, injector=self.injector))
        result.scope_name = scope_name
        if settings:
            result.update_settings(settings)
        return result

    def injector_for_scope(self, scope_name: str) -> Injector:
        """Fetch the injector for a specific scope.

        Args:
            scope_name: The unique scope identifier
        """
        if scope_name == self.scope_name:
            return self.injector
        for scope in self._scopes:
            if scope.name == scope_name:
                return scope.injector
        return None

    async def inject(
        self,
        base_cls: type,
        settings: Mapping[str, object] = None,
        *,
        required: bool = True
    ) -> object:
        """
        Get the provided instance of a given class identifier.

        Args:
            cls: The base class to retrieve an instance of
            settings: An optional mapping providing configuration to the provider

        Returns:
            An instance of the base class, or None

        """
        return await self.injector.inject(base_cls, settings, required=required)

    def copy(self) -> "InjectionContext":
        """Produce a copy of the injector instance."""
        result = copy.copy(self)
        result._injector = self.injector.copy()
        result._scopes = self._scopes.copy()
        return result

Classes

class InjectionContext (*, settings: Mapping[str, object] = None, enforce_typing: bool = True)

Manager for configuration settings and class providers.

Initialize a ServiceConfig.

Expand source code
class InjectionContext(BaseInjector):
    """Manager for configuration settings and class providers."""

    ROOT_SCOPE = "application"

    def __init__(
        self, *, settings: Mapping[str, object] = None, enforce_typing: bool = True
    ):
        """Initialize a `ServiceConfig`."""
        self._injector = Injector(settings, enforce_typing=enforce_typing)
        self._scope_name = InjectionContext.ROOT_SCOPE
        self._scopes = []

    @property
    def injector(self) -> Injector:
        """Accessor for scope-specific injector."""
        return self._injector

    @injector.setter
    def injector(self, injector: Injector):
        """Setter for scope-specific injector."""
        self._injector = injector

    @property
    def scope_name(self) -> str:
        """Accessor for the current scope name."""
        return self._scope_name

    @scope_name.setter
    def scope_name(self, scope_name: str):
        """Accessor for the current scope name."""
        self._scope_name = scope_name

    @property
    def settings(self) -> Settings:
        """Accessor for scope-specific settings."""
        return self.injector.settings

    @settings.setter
    def settings(self, settings: Settings):
        """Setter for scope-specific settings."""
        self.injector.settings = settings

    def update_settings(self, settings: Mapping[str, object]):
        """Update the scope with additional settings."""
        if settings:
            self.injector.settings = self.injector.settings.extend(settings)

    def start_scope(
        self, scope_name: str, settings: Mapping[str, object] = None
    ) -> "InjectionContext":
        """Begin a new named scope.

        Args:
            scope_name: The unique name for the scope being entered
            settings: An optional mapping of additional settings to apply

        Returns:
            A new injection context representing the scope

        """
        if not scope_name:
            raise InjectionContextError("Scope name must be non-empty")
        if self.scope_name == scope_name:
            raise InjectionContextError(
                "Cannot re-enter scope: {}".format(scope_name))
        for scope in self._scopes:
            if scope.name == scope_name:
                raise InjectionContextError(
                    "Cannot re-enter scope: {}".format(scope_name)
                )
        result = self.copy()
        result._scopes.append(
            Scope(name=self.scope_name, injector=self.injector))
        result.scope_name = scope_name
        if settings:
            result.update_settings(settings)
        return result

    def injector_for_scope(self, scope_name: str) -> Injector:
        """Fetch the injector for a specific scope.

        Args:
            scope_name: The unique scope identifier
        """
        if scope_name == self.scope_name:
            return self.injector
        for scope in self._scopes:
            if scope.name == scope_name:
                return scope.injector
        return None

    async def inject(
        self,
        base_cls: type,
        settings: Mapping[str, object] = None,
        *,
        required: bool = True
    ) -> object:
        """
        Get the provided instance of a given class identifier.

        Args:
            cls: The base class to retrieve an instance of
            settings: An optional mapping providing configuration to the provider

        Returns:
            An instance of the base class, or None

        """
        return await self.injector.inject(base_cls, settings, required=required)

    def copy(self) -> "InjectionContext":
        """Produce a copy of the injector instance."""
        result = copy.copy(self)
        result._injector = self.injector.copy()
        result._scopes = self._scopes.copy()
        return result

Ancestors

  • aries_cloudagent.config.base.BaseInjector
  • abc.ABC

Class variables

var ROOT_SCOPE

Instance variables

var injectorInjector

Accessor for scope-specific injector.

Expand source code
@property
def injector(self) -> Injector:
    """Accessor for scope-specific injector."""
    return self._injector
var scope_name : str

Accessor for the current scope name.

Expand source code
@property
def scope_name(self) -> str:
    """Accessor for the current scope name."""
    return self._scope_name
var settings : aries_cloudagent.config.settings.Settings

Accessor for scope-specific settings.

Expand source code
@property
def settings(self) -> Settings:
    """Accessor for scope-specific settings."""
    return self.injector.settings

Methods

def copy(self) ‑> InjectionContext

Produce a copy of the injector instance.

Expand source code
def copy(self) -> "InjectionContext":
    """Produce a copy of the injector instance."""
    result = copy.copy(self)
    result._injector = self.injector.copy()
    result._scopes = self._scopes.copy()
    return result
async def inject(self, base_cls: type, settings: Mapping[str, object] = None, *, required: bool = True) ‑> object

Get the provided instance of a given class identifier.

Args

cls
The base class to retrieve an instance of
settings
An optional mapping providing configuration to the provider

Returns

An instance of the base class, or None

Expand source code
async def inject(
    self,
    base_cls: type,
    settings: Mapping[str, object] = None,
    *,
    required: bool = True
) -> object:
    """
    Get the provided instance of a given class identifier.

    Args:
        cls: The base class to retrieve an instance of
        settings: An optional mapping providing configuration to the provider

    Returns:
        An instance of the base class, or None

    """
    return await self.injector.inject(base_cls, settings, required=required)
def injector_for_scope(self, scope_name: str) ‑> Injector

Fetch the injector for a specific scope.

Args

scope_name
The unique scope identifier
Expand source code
def injector_for_scope(self, scope_name: str) -> Injector:
    """Fetch the injector for a specific scope.

    Args:
        scope_name: The unique scope identifier
    """
    if scope_name == self.scope_name:
        return self.injector
    for scope in self._scopes:
        if scope.name == scope_name:
            return scope.injector
    return None
def start_scope(self, scope_name: str, settings: Mapping[str, object] = None) ‑> InjectionContext

Begin a new named scope.

Args

scope_name
The unique name for the scope being entered
settings
An optional mapping of additional settings to apply

Returns

A new injection context representing the scope

Expand source code
def start_scope(
    self, scope_name: str, settings: Mapping[str, object] = None
) -> "InjectionContext":
    """Begin a new named scope.

    Args:
        scope_name: The unique name for the scope being entered
        settings: An optional mapping of additional settings to apply

    Returns:
        A new injection context representing the scope

    """
    if not scope_name:
        raise InjectionContextError("Scope name must be non-empty")
    if self.scope_name == scope_name:
        raise InjectionContextError(
            "Cannot re-enter scope: {}".format(scope_name))
    for scope in self._scopes:
        if scope.name == scope_name:
            raise InjectionContextError(
                "Cannot re-enter scope: {}".format(scope_name)
            )
    result = self.copy()
    result._scopes.append(
        Scope(name=self.scope_name, injector=self.injector))
    result.scope_name = scope_name
    if settings:
        result.update_settings(settings)
    return result
def update_settings(self, settings: Mapping[str, object])

Update the scope with additional settings.

Expand source code
def update_settings(self, settings: Mapping[str, object]):
    """Update the scope with additional settings."""
    if settings:
        self.injector.settings = self.injector.settings.extend(settings)
class InjectionContextError (*args, error_code: str = None, **kwargs)

Base class for issues in the injection context.

Initialize a BaseError instance.

Expand source code
class InjectionContextError(InjectorError):
    """Base class for issues in the injection context."""

Ancestors

  • aries_cloudagent.config.base.InjectorError
  • aries_cloudagent.config.base.ConfigError
  • aries_cloudagent.core.error.BaseError
  • builtins.Exception
  • builtins.BaseException
class Scope (name, injector)

Scope(name, injector)

Ancestors

  • builtins.tuple

Instance variables

var injector

Alias for field number 1

var name

Alias for field number 0