Skip to content

Config

plateforme.core.config

This module provides utilities for managing configuration classes within the Plateforme framework.

Config module-attribute

Config = TypeVar('Config', bound='ConfigWrapper')

A type variable for configuration classes.

ConfigType module-attribute

ConfigType = Type['ConfigWrapper']

A type alias for configuration classes.

ConfigFieldInfo module-attribute

ConfigFieldInfo = FieldInfo['ConfigType']

A type alias for a configuration wrapper field information.

ConfigSource module-attribute

ConfigSource = Type[Dict[str, Any]]

A type alias for configuration dictionary sources.

ConfigWrapperMeta

Bases: type

A metaclass for configuration wrappers.

collect_config_fields

collect_config_fields(
    bases: tuple[type, ...],
    types_namespace: dict[str, Any] | None,
    *sources: ConfigSource,
    **defaults: Any,
) -> dict[str, ConfigFieldInfo]

Collect configuration fields for the configuration wrapper.

The configuration fields are collected from the wrapper class definition and the provided configuration dictionary sources. The configuration fields are checked for consistency in type across sources and for the presence of default values for non-required fields.

Parameters:

Name Type Description Default
bases tuple[type, ...]

The configuration wrapper base classes to collect the configuration fields from.

required
types_namespace dict[str, Any] | None

The types namespace of the configuration wrapper to look for type hints.

required
*sources ConfigSource

The configuration dictionary sources to collect the fields from. These dictionaries must be subclasses of a typed dictionary.

()
**defaults Any

Optional default values to provide in addition to those in the configuration wrapper namespace. It is typically set with keyword arguments in the configuration wrapper definition.

{}

Returns:

Type Description
dict[str, ConfigFieldInfo]

A dictionary containing the configuration fields collected from the

dict[str, ConfigFieldInfo]

wrapper class definition and the configuration dictionary sources.

Raises:

Type Description
AttributeError

If a configuration field conflicts with a protected member attribute or is not present in the class namespace when setting a default value.

TypeError

If a configuration dictionary source is not a valid subclass of a typed dictionary or if a configuration field has different annotations in the configuration dictionary sources.

ValueError

If a not required configuration field does not have a default value.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def collect_config_fields(
    cls,
    bases: tuple[type, ...],
    types_namespace: dict[str, Any] | None,
    *sources: ConfigSource,
    **defaults: Any,
) -> dict[str, ConfigFieldInfo]:
    """Collect configuration fields for the configuration wrapper.

    The configuration fields are collected from the wrapper class
    definition and the provided configuration dictionary sources. The
    configuration fields are checked for consistency in type across sources
    and for the presence of default values for non-required fields.

    Args:
        bases: The configuration wrapper base classes to collect the
            configuration fields from.
        types_namespace: The types namespace of the configuration wrapper
            to look for type hints.
        *sources: The configuration dictionary sources to collect the
            fields from. These dictionaries must be subclasses of a typed
            dictionary.
        **defaults: Optional default values to provide in addition to those
            in the configuration wrapper namespace. It is typically set
            with keyword arguments in the configuration wrapper definition.

    Returns:
        A dictionary containing the configuration fields collected from the
        wrapper class definition and the configuration dictionary sources.

    Raises:
        AttributeError: If a configuration field conflicts with a protected
            member attribute or is not present in the class namespace when
            setting a default value.
        TypeError: If a configuration dictionary source is not a valid
            subclass of a typed dictionary or if a configuration field has
            different annotations in the configuration dictionary sources.
        ValueError: If a not required configuration field does not have a
            default value.
    """
    fields: dict[str, ConfigFieldInfo] = {}

    # Store the configuration fields to check for default values. This is
    # done to ensure that all non-required fields specified in the
    # configuration dictionary sources have default values.
    check_for_default: set[str] = set()

    # Collect configuration fields from the dictionary sources
    for source in sources:
        # Check if the source is a typed dictionary
        if not issubclass(source, dict):
            raise TypeError(
                f"A configuration dictionary source must be a subclass "
                f"of a typed dictionary. Got: {source}."
            )

        # Retrieve annotations and total flag from the dictionary source
        # to determine whether the configuration fields are required.
        total = getattr(source, '__total__', False)
        annotations: dict[str, Any] = \
            getattr(source, '__annotations__', {})

        for name, value in annotations.items():
            # Skip private and dunder attributes
            if name.startswith('_'):
                continue
            # Check protected attributes
            if match_any_pattern(name, *PROTECTED_ATTRS):
                raise AttributeError(
                    f"Source configuration field {name!r} conflicts with "
                    f"a protected member attribute."
                )
            # Check field shadowing in base classes
            for base in bases:
                if hasattr(base, name):
                    warnings.warn(
                        f"Source configuration field {name!r} shadows an "
                        f"attribute in base class {base.__qualname__!r}.",
                        UserWarning,
                    )

            # Handle required fields and default values check
            if not is_required(value, total):
                # Add the field to the default value check if it is not
                # required, as a value may not be provided for it.
                check_for_default.add(name)
            else:
                # Remove the field from the default value check if it is
                # required, as a value must be provided for it.
                check_for_default.discard(name)

            # Create field information from the annotation
            field_info = ConfigFieldInfo.from_annotation(
                value, owner=cls, name=name  # type: ignore
            )

            # Check if the configuration field is already defined
            if name in fields \
                    and fields[name].annotation != field_info.annotation:
                raise TypeError(
                    f"Source configuration field {name!r} must have the "
                    f"same annotation in all configuration sources. Got: "
                    f"{fields[name].annotation!r} and "
                    f"{field_info.annotation!r}."
                )

            fields[name] = field_info

    # Retrieve type hints and names from the configuration wrapper class
    # definition. The type names derived from annotations keys are used to
    # check if a field is defined in the class or in one of its bases.
    type_hints = get_cls_type_hints_lenient(cls, types_namespace)
    type_names = cls.__dict__.get('__annotations__', {}).keys()

    for name, value in type_hints.items():
        # Skip private and dunder attributes
        if name.startswith('_'):
            continue
        # Check protected attributes
        if match_any_pattern(name, *PROTECTED_ATTRS):
            raise AttributeError(
                f"Namespace configuration field {name!r} conflicts with a "
                f"protected member attribute."
            )
        # Check field shadowing in base classes
        for base in bases:
            if hasattr(base, name):
                warnings.warn(
                    f"Namespace configuration field {name!r} shadows an "
                    f"attribute in base class {base.__qualname__!r}.",
                    UserWarning,
                )

        try:
            default = getattr(cls, name, Undefined)
            if default is Undefined:
                raise AttributeError
        except AttributeError:
            if name in type_names:
                field_info = ConfigFieldInfo.from_annotation(
                    value, owner=cls, name=name  # type: ignore
                )
            else:
                # If field has no default value and is not in type names,
                # then it may be defined in a base class.
                fields_lookup: dict[str, ConfigFieldInfo] = {}
                for base in cls.__bases__[::-1]:
                    fields_base = getattr(base, '__config_fields__', {})
                    fields_lookup.update(fields_base)
                if name in fields_lookup:
                    # The field is present on one or multiple base classes
                    field_info = copy(fields_lookup[name])
                else:
                    # The field is not found on any base classes
                    field_info = ConfigFieldInfo.from_annotation(
                        value, owner=cls, name=name  # type: ignore
                    )
        else:
            field_info = ConfigFieldInfo.from_annotated_attribute(
                value, default, owner=cls, name=name  # type: ignore
            )
            # Removed field attributes from the class namespace to match
            # the behaviour of annotation-only fields and to avoid false
            # positives in the attribute check above.
            try:
                delattr(cls, name)
            except AttributeError:
                pass  # Indicates the attribute is on a parent class

        # Check if the configuration field is already defined
        if name in fields \
                and fields[name].annotation != field_info.annotation:
            raise TypeError(
                f"Namespace configuration field {name!r} must have the "
                f"same annotation than in all configuration sources. Got: "
                f"{fields[name].annotation!r} and "
                f"{field_info.annotation!r}."
            )

        fields[name] = field_info

    # Update the configuration fields with the default values provided in
    # the class keyword arguments.
    for name, value in defaults.items():
        # Check if the default value is provided for a non-existing field
        if name not in fields:
            raise AttributeError(
                f"Configuration field {name!r} is not present in the "
                f"wrapped configuration."
            )
        # Check if the default value is of the correct type
        annotation = fields[name].annotation
        if annotation is not None \
                and not isinstance(value, annotation):
            raise TypeError(
                f"Default value for configuration field {name!r} must be "
                f"of type {annotation.__name__!r}. Got: "
                f"{type(value).__name__!r}."
            )
        fields[name].default = value

    # Check wether all non required fields have default values
    for name in check_for_default:
        if fields[name].default is Undefined \
                and fields[name].default_factory is None:
            raise ValueError(
                f"Configuration field {name!r} must have a default value "
                f"as it is marked as not required in the configuration "
                f"dictionary sources."
            )

    return fields

ConfigWrapper

ConfigWrapper(
    __owner: Any | None = None,
    __defaults: dict[str, Any] | None = None,
    __partial_init: bool = False,
    /,
    **data: Any,
)

Bases: Representation

A base configuration wrapper class.

Initialize the configuration class with the given data.

Parameters:

Name Type Description Default
__owner Any | None

The owner of the configuration instance. It can be any object or type that uses the configuration instance. Defaults to None.

None
__defaults dict[str, Any] | None

The default values to initialize the configuration instance with. Defaults to None.

None
__partial_init bool

Flag indicating whether to partially initialize the configuration instance. Defaults to False.

False
**data Any

The data as keyword arguments to initialize the configuration instance with.

{}
Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def __init__(
    self,
    __owner: Any | None = None,
    __defaults: dict[str, Any] | None = None,
    __partial_init: bool = False,
    /,
    **data: Any,
) -> None:
    """Initialize the configuration class with the given data.

    Args:
        __owner: The owner of the configuration instance. It can be any
            object or type that uses the configuration instance.
            Defaults to ``None``.
        __defaults: The default values to initialize the configuration
            instance with. Defaults to ``None``.
        __partial_init: Flag indicating whether  to partially initialize
            the configuration instance. Defaults to ``False``.
        **data: The data as keyword arguments to initialize the
            configuration instance with.
    """
    # Initialize configuration instance
    self.__config_owner__ = __owner \
        or getattr(self, '__config_owner__', None)
    self.__config_defaults__: dict[str, Any] = __defaults or {}
    with self.context(allow_mutation=True):
        self.update(data)

    # Validate configuration instance
    if not __partial_init:
        self.validate()

create classmethod

create(
    owner: Any | None = None,
    defaults: dict[str, Any] | None = None,
    partial_init: bool = False,
    *,
    data: dict[str, Any] | None = None,
) -> Self

Create a new configuration instance.

This method is typically used internally to create a new configuration class with a specific owner and partial initialization flag. It is an alternative to the __init__ method for creating a new configuration instance.

Parameters:

Name Type Description Default
owner Any | None

The owner of the configuration instance.

None
defaults dict[str, Any] | None

The default values to initialize the configuration instance with. Defaults to None.

None
partial_init bool

Flag indicating whether to partially initialize the configuration instance. Defaults to False.

False
data dict[str, Any] | None

The data to initialize the configuration instance with. Defaults to None.

None

Returns:

Type Description
Self

The new configuration instance created.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
@classmethod
def create(
    cls,
    owner: Any | None = None,
    defaults: dict[str, Any] | None = None,
    partial_init: bool = False,
    *,
    data: dict[str, Any] | None = None,
) -> Self:
    """Create a new configuration instance.

    This method is typically used internally to create a new configuration
    class with a specific owner and partial initialization flag. It is an
    alternative to the `__init__` method for creating a new configuration
    instance.

    Args:
        owner: The owner of the configuration instance.
        defaults: The default values to initialize the configuration
            instance with. Defaults to ``None``.
        partial_init: Flag indicating whether to partially initialize the
            configuration instance. Defaults to ``False``.
        data: The data to initialize the configuration instance with.
            Defaults to ``None``.

    Returns:
        The new configuration instance created.
    """
    return cls(owner, defaults, partial_init, **(data or {}))

from_meta classmethod

from_meta(
    owner: type[Any],
    bases: tuple[type, ...],
    namespace: dict[str, Any],
    /,
    config_attr: str = "__config__",
    partial_init: bool = False,
    data: dict[str, Any] | None = None,
) -> Self

Create a new configuration instance from a class constructor.

This method is typically used internally to create a new configuration class from the meta configuration of a model, package, resource, or service. It merges the configuration of the given bases, the namespace, and the keyword arguments to create a new configuration class.

Parameters:

Name Type Description Default
owner type[Any]

The owner of the configuration instance. It should be the class that is being created from the meta configuration.

required
bases tuple[type, ...]

The configurable base classes to merge.

required
namespace dict[str, Any]

The configurable namespace to merge.

required
config_attr str

The configurable attribute name used to extract the configuration dictionary from the bases and the namespace of the configurable class. Defaults to '__config__'.

'__config__'
partial_init bool

Flag indicating whether to partially initialize the configuration instance. Defaults to False.

False
data dict[str, Any] | None

The data to initialize the configuration instance with. Defaults to None.

None

Returns:

Type Description
Self

The new configuration instance created from the given meta

Self

configuration.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
@classmethod
def from_meta(
    cls,
    owner: type[Any],
    bases: tuple[type, ...],
    namespace: dict[str, Any],
    /,
    config_attr: str = '__config__',
    partial_init: bool = False,
    data: dict[str, Any] | None = None,
) -> Self:
    """Create a new configuration instance from a class constructor.

    This method is typically used internally to create a new configuration
    class from the meta configuration of a model, package, resource, or
    service. It merges the configuration of the given bases, the namespace,
    and the keyword arguments to create a new configuration class.

    Args:
        owner: The owner of the configuration instance. It should be the
            class that is being created from the meta configuration.
        bases: The configurable base classes to merge.
        namespace: The configurable namespace to merge.
        config_attr: The configurable attribute name used to extract the
            configuration dictionary from the bases and the namespace of
            the configurable class. Defaults to ``'__config__'``.
        partial_init: Flag indicating whether to partially initialize the
            configuration instance. Defaults to ``False``.
        data: The data to initialize the configuration instance with.
            Defaults to ``None``.

    Returns:
        The new configuration instance created from the given meta
        configuration.
    """
    with cls.context(allow_mutation=True):
        # Build configuration instance
        config = cls(owner, {}, True)

        for base in bases:
            base_config = getattr(base, config_attr, {})
            if callable(base_config):
                base_config = base_config()
            config.merge(base_config)

        namespace_config = namespace.get(config_attr, {})
        if callable(namespace_config):
            namespace_config = namespace_config()
        config.merge(namespace_config)

        config.merge(data or {})

        # Validate configuration instance
        if not partial_init:
            config.validate()

    return config

post_init

post_init() -> None

Post-initialization method for the configuration class.

Override this method to perform additional initialization steps after the configuration instance has been created. This method is called automatically after the configuration instance has been initialized, unless the partial_init flag is set to True.

Note

See the validate method for more information on the validation process of the configuration instance.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def post_init(self) -> None:
    """Post-initialization method for the configuration class.

    Override this method to perform additional initialization steps after
    the configuration instance has been created. This method is called
    automatically after the configuration instance has been initialized,
    unless the `partial_init` flag is set to ``True``.

    Note:
        See the `validate` method for more information on the validation
        process of the configuration instance.
    """
    ...

validate

validate(
    *,
    strict: bool | None = None,
    context: dict[str, Any] | None = None,
) -> None

Validate the configuration instance.

It post-initializes the configuration instance, checks for any missing required fields and validates the assignments of the configuration values based on the configuration fields information and the current validation context. This is performed automatically upon initialization of the configuration instance.

Parameters:

Name Type Description Default
strict bool | None

Whether to enforce strict validation. Defaults to None.

None
context dict[str, Any] | None

The context to use for validation. Defaults to None.

None

Raises:

Type Description
ValueError

If the configuration instance has undefined values for required fields.

ValidationError

If the assignment of a value is invalid based on the configuration fields information and the current validation context.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def validate(
    self,
    *,
    strict: bool | None = None,
    context: dict[str, Any] | None = None,
) -> None:
    """Validate the configuration instance.

    It post-initializes the configuration instance, checks for any missing
    required fields and validates the assignments of the configuration
    values based on the configuration fields information and the current
    validation context. This is performed automatically upon initialization
    of the configuration instance.

    Args:
        strict: Whether to enforce strict validation. Defaults to ``None``.
        context: The context to use for validation. Defaults to ``None``.

    Raises:
        ValueError: If the configuration instance has undefined values for
            required fields.
        ValidationError: If the assignment of a value is invalid based on
            the configuration fields information and the current validation
            context.
    """
    # Perform post-initialization
    self.post_init()

    # Validate for missing required fields
    config_missing = [
        key for key, field in self.__config_fields__.items()
        if field.is_required() and self[key] is Undefined
    ]
    if config_missing:
        raise ValueError(
            f"Undefined values for configuration "
            f"{self.__class__.__qualname__!r} required fields: "
            f"{', '.join(config_missing)}."
        )

    # Validate assignments
    for key, value in self.entries(scope='set').items():
        if not strict and value is Deferred:
            continue
        if key in self.__config_validators__:
            validator = self.__config_validators__[key].validate_python
            value = validator(value, strict=strict, context=context)
        self.__dict__[key] = value

context staticmethod

context(
    *, allow_mutation: bool | None = None
) -> Iterator[bool]

Context manager for the configuration instance.

If the frozen mutation flag is not specified, the current frozen mutation flag is used if available, otherwise it defaults to False.

Parameters:

Name Type Description Default
allow_mutation bool | None

Flag indicating whether to allow frozen mutation of the configuration instance. When set to False, it prevents any changes by setting the frozen flag to True. If not specified, the current frozen mutation flag is used if available, otherwise it resolves to False. Defaults to None.

None
Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
@staticmethod
@contextmanager
def context(
    *, allow_mutation: bool | None = None,
) -> Iterator[bool]:
    """Context manager for the configuration instance.

    If the frozen mutation flag is not specified, the current frozen
    mutation flag is used if available, otherwise it defaults to ``False``.

    Args:
        allow_mutation: Flag indicating whether to allow frozen mutation
            of the configuration instance. When set to ``False``, it
            prevents any changes by setting the frozen flag to ``True``.
            If not specified, the current frozen mutation flag is used if
            available, otherwise it resolves to ``False``.
            Defaults to ``None``.
    """
    context = FROZEN_CONTEXT.get()

    # Set frozen mutation flag
    if allow_mutation is None:
        if context is not None:
            frozen = context
        frozen = True
    else:
        frozen = not allow_mutation

    # Yield and reset frozen mutation flag
    token = FROZEN_CONTEXT.set(frozen)
    try:
        yield frozen
    finally:
        FROZEN_CONTEXT.reset(token)

clear

clear() -> None

Clear the configuration dictionary and reset all values.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def clear(self) -> None:
    """Clear the configuration dictionary and reset all values."""
    for key in self.__config_fields__:
        self.__dict__.pop(key, None)

copy

copy() -> Self

Return a shallow copy of the configuration dictionary.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def copy(self) -> Self:
    """Return a shallow copy of the configuration dictionary."""
    return self.__class__(
        self.__config_owner__,
        self.__config_defaults__.copy(),
        False,
        **self.entries(scope='set')
    )

merge

merge(
    *configs: Self | dict[str, Any],
    setdefault: bool = False,
) -> None

Merge the configuration with other configurations.

It merges the configuration with the provided configuration instances or dictionaries. The precedence of the rightmost configuration is higher than the leftmost configuration. This can be changed by setting the setdefault argument to True.

Parameters:

Name Type Description Default
*configs Self | dict[str, Any]

The configuration instances or dictionaries to merge with the target configuration dictionary.

()
setdefault bool

Flag indicating whether to set the default values for the configuration keys if they are not already set. This modifies the behavior of the merge operation, making the precedence of the leftmost configuration higher than the rightmost configuration. Defaults to False (rightmost precedence).

False
Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def merge(
    self,
    *configs: Self | dict[str, Any],
    setdefault: bool = False,
) -> None:
    """Merge the configuration with other configurations.

    It merges the configuration with the provided configuration instances
    or dictionaries. The precedence of the rightmost configuration is
    higher than the leftmost configuration. This can be changed by setting
    the `setdefault` argument to ``True``.

    Args:
        *configs: The configuration instances or dictionaries to merge with
            the target configuration dictionary.
        setdefault: Flag indicating whether to set the default values for
            the configuration keys if they are not already set.
            This modifies the behavior of the merge operation, making the
            precedence of the leftmost configuration higher than the
            rightmost configuration.
            Defaults to ``False`` (rightmost precedence).
    """
    for config in configs:
        # Retrieve the configuration dictionary
        if isinstance(config, self.__class__):
            config_dict = {
                key: value
                for key, value in config.__dict__.items()
                if key in config.__config_fields__
            }
        elif isinstance(config, dict):
            config_dict = config.copy()
        else:
            raise TypeError(
                f"Invalid configuration type {type(config).__name__!r} "
                f"for {self.__class__.__qualname__!r}, it must be a "
                f"dictionary or a configuration instance."
            )
        # Merge with the target configuration dictionary
        if setdefault:
            for key, value in config_dict.items():
                self.setdefault(key, value)
        else:
            self.update(config_dict)

check

check(
    key: str,
    *,
    scope: Literal["all", "default", "set"] = "all",
    raise_errors: bool = True,
) -> bool

Check if the configuration key exists in the given scope.

Parameters:

Name Type Description Default
key str

The configuration key to check for.

required
scope Literal['all', 'default', 'set']

The scope to check for the configuration key. It can be either 'all' to check in all configuration entries, 'default' to check in configuration entries with default values not undefined, or 'set' to check in only the configuration entries that have been explicitly set. Defaults to 'all'.

'all'
raise_errors bool

Flag indicating whether to raise an error if the configuration key is not defined for the configuration wrapper. Defaults to True.

True

Returns:

Type Description
bool

A boolean indicating whether the configuration key exists in the

bool

specified scope.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def check(
    self,
    key: str,
    *,
    scope: Literal['all', 'default', 'set'] = 'all',
    raise_errors: bool = True,
) -> bool:
    """Check if the configuration key exists in the given scope.

    Args:
        key: The configuration key to check for.
        scope: The scope to check for the configuration key. It can be
            either ``'all'`` to check in all configuration entries,
            ``'default'`` to check in configuration entries with default
            values not undefined, or ``'set'`` to check in only the
            configuration entries that have been explicitly set.
            Defaults to ``'all'``.
        raise_errors: Flag indicating whether to raise an error if the
            configuration key is not defined for the configuration wrapper.
            Defaults to ``True``.

    Returns:
        A boolean indicating whether the configuration key exists in the
        specified scope.
    """
    if key not in self.__config_fields__:
        if not raise_errors:
            return False
        raise KeyError(
            f"Configuration key {key!r} cannot be checked as it is not "
            f"defined for wrapper {self.__class__.__qualname__!r}."
        )
    if scope == 'default':
        return key not in self.__dict__
    if scope == 'set':
        return key in self.__dict__
    return True

entries

entries(
    *,
    scope: Literal["all", "default", "set"] = "all",
    default_mode: Literal[
        "preserve", "unwrap", "wrap"
    ] = "unwrap",
    include_keys: Iterable[str] | None = None,
    exclude_keys: Iterable[str] | None = None,
    include_metadata: Iterable[Any] | None = None,
    exclude_metadata: Iterable[Any] | None = None,
) -> dict[str, Any]

Return the configuration dictionary.

It returns the configuration dictionary based on the specified scope, and keys and extra information to filter the configuration dictionary entries.

Parameters:

Name Type Description Default
scope Literal['all', 'default', 'set']

The scope of the configuration dictionary to return. It can be either 'all' to return all configuration entries, 'default' to return all configuration entries with their default values, or 'set' to return only the configuration entries that have been explicitly set. Defaults to 'all'.

'all'
default_mode Literal['preserve', 'unwrap', 'wrap']

The default mode to use when returning a default entry from the configuration dictionary. It can be either 'preserve' to keep the default value as is, 'unwrap' to unwrap the default value, or 'wrap' to wrap the default value with a default placeholder. Defaults to 'unwrap'.

'unwrap'
include_keys Iterable[str] | None

The keys to include from the configuration dictionary entries. Defaults to None.

None
exclude_keys Iterable[str] | None

The keys to exclude from the configuration dictionary entries. Defaults to None.

None
include_metadata Iterable[Any] | None

The metadata information to include from the configuration dictionary entries. Defaults to None.

None
exclude_metadata Iterable[Any] | None

The metadata information to exclude from the configuration dictionary entries. Defaults to None.

None

Returns:

Type Description
dict[str, Any]

A dictionary containing the configuration entries based on the

dict[str, Any]

specified scope and extra information.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def entries(
    self,
    *,
    scope: Literal['all', 'default', 'set'] = 'all',
    default_mode: Literal['preserve', 'unwrap', 'wrap'] = 'unwrap',
    include_keys: Iterable[str] | None = None,
    exclude_keys: Iterable[str] | None = None,
    include_metadata: Iterable[Any] | None = None,
    exclude_metadata: Iterable[Any] | None = None,
) -> dict[str, Any]:
    """Return the configuration dictionary.

    It returns the configuration dictionary based on the specified scope,
    and keys and extra information to filter the configuration dictionary
    entries.

    Args:
        scope: The scope of the configuration dictionary to return. It can
            be either ``'all'`` to return all configuration entries,
            ``'default'`` to return all configuration entries with their
            default values, or ``'set'`` to return only the configuration
            entries that have been explicitly set. Defaults to ``'all'``.
        default_mode: The default mode to use when returning a default
            entry from the configuration dictionary. It can be either
            ``'preserve'`` to keep the default value as is, ``'unwrap'`` to
            unwrap the default value, or ``'wrap'`` to wrap the default
            value with a default placeholder. Defaults to ``'unwrap'``.
        include_keys: The keys to include from the configuration dictionary
            entries. Defaults to ``None``.
        exclude_keys: The keys to exclude from the configuration dictionary
            entries. Defaults to ``None``.
        include_metadata: The metadata information to include from the
            configuration dictionary entries. Defaults to ``None``.
        exclude_metadata: The metadata information to exclude from the
            configuration dictionary entries. Defaults to ``None``.

    Returns:
        A dictionary containing the configuration entries based on the
        specified scope and extra information.
    """
    # Retrieve the configuration dictionary based on the specified scope
    config_dict: dict[str, Any] = {}
    if scope == 'default':
        for key in self.__config_fields__:
            if key in self.__dict__:
                continue
            config_dict[key] = self.get(key, default_mode=default_mode)
    elif scope == 'set':
        for key in self.__config_fields__:
            if key not in self.__dict__:
                continue
            config_dict[key] = self.get(key, default_mode=default_mode)
    else:
        for key in self.__config_fields__:
            config_dict[key] = self.get(key, default_mode=default_mode)

    # Build the keys and metadata sets to include and exclude from the
    # configuration dictionary entries.
    incex_keys = [include_keys, exclude_keys]
    for count, value in enumerate(incex_keys):
        if value is not None:
            if isinstance(value, type) and \
                    issubclass(value, ConfigWrapper):
                value = value.__config_fields__.keys()
            incex_keys[count] = set(value)

    incex_metadata = [include_metadata, exclude_metadata]
    for count, value in enumerate(incex_metadata):
        if value is not None:
            incex_metadata[count] = set(value)

    # Return directly if no keys or metadata filtering is provided.
    if not any(incex_keys) and not any(incex_metadata):
        return config_dict

    # Filter the configuration dictionary based on the information and keys
    # if provided in the "with" arguments.
    for key in list(config_dict.keys()):
        if incex_keys[0] is not None and key not in incex_keys[0]:
            config_dict.pop(key)
        elif incex_keys[1] is not None and key in incex_keys[1]:
            config_dict.pop(key)
        elif incex_metadata[0] is not None and not all(
            metadata in self.__config_fields__[key].metadata
            for metadata in incex_metadata[0]
        ):
            config_dict.pop(key)
        elif incex_metadata[1] is not None and any(
            metadata in self.__config_fields__[key].metadata
            for metadata in incex_metadata[1]
        ):
            config_dict.pop(key)

    return config_dict

keys

keys() -> KeysView[str]

Return the configuration keys.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def keys(self) -> KeysView[str]:
    """Return the configuration keys."""
    return KeysView(self.entries())

values

values() -> ValuesView[Any]

Return the configuration values.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def values(self) -> ValuesView[Any]:
    """Return the configuration values."""
    return ValuesView(self.entries())

items

items() -> ItemsView[str, Any]

Return the configuration items.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def items(self) -> ItemsView[str, Any]:
    """Return the configuration items."""
    return ItemsView(self.entries())

get

get(key: str) -> Any
get(key: str, default: Any) -> Any
get(
    key: str,
    default: Any = Undefined,
    *,
    default_mode: Literal[
        "preserve", "unwrap", "wrap"
    ] = "unwrap",
) -> Any
get(
    key: str,
    default: Any = Undefined,
    *,
    default_mode: Literal[
        "preserve", "unwrap", "wrap"
    ] = "unwrap",
) -> Any

Get the value for the specified key if set otherwise the default.

Parameters:

Name Type Description Default
key str

The configuration key to get the value for.

required
default Any

The default value to return if the key is not set.

Undefined
default_mode Literal['preserve', 'unwrap', 'wrap']

The default mode to use when returning a default value from the configuration dictionary. It can be either 'preserve' to keep the default value as is, 'unwrap' to unwrap the default value, or 'wrap' to wrap the default value with a placeholder. Defaults to 'unwrap'.

'unwrap'
Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def get(
    self, key: str,
    default: Any = Undefined,
    *,
    default_mode: Literal['preserve', 'unwrap', 'wrap'] = 'unwrap',
) -> Any:
    """Get the value for the specified key if set otherwise the default.

    Args:
        key: The configuration key to get the value for.
        default: The default value to return if the key is not set.
        default_mode: The default mode to use when returning a default
            value from the configuration dictionary. It can be either
            ``'preserve'`` to keep the default value as is, ``'unwrap'`` to
            unwrap the default value, or ``'wrap'`` to wrap the default
            value with a placeholder. Defaults to ``'unwrap'``.
    """
    if key not in self.__config_fields__:
        raise KeyError(
            f"Configuration key {key!r} cannot be retrieved as it is not "
            f"defined for wrapper {self.__class__.__qualname__!r}."
        )
    if key in self.__dict__:
        return self.__dict__[key]
    if default is Undefined:
        return self.getdefault(key, mode=default_mode)
    if default_mode == 'wrap':
        return Default(default)
    if default_mode == 'unwrap':
        return get_value_or_default(default)
    return default

pop

pop(key: str) -> Any
pop(key: str, default: Any) -> Any
pop(
    key: str,
    default: Any = Undefined,
    *,
    default_mode: Literal[
        "preserve", "unwrap", "wrap"
    ] = "unwrap",
) -> Any
pop(
    key: str,
    default: Any = Undefined,
    *,
    default_mode: Literal[
        "preserve", "unwrap", "wrap"
    ] = "unwrap",
) -> Any

Pop the specified key if set and return its corresponding value.

Parameters:

Name Type Description Default
key str

The configuration key to pop the value for.

required
default Any

The default value to return if the key is not set.

Undefined
default_mode Literal['preserve', 'unwrap', 'wrap']

The default mode to use when returning a default value from the configuration dictionary. It can be either 'preserve' to keep the default value as is, 'unwrap' to unwrap the default value, or 'wrap' to wrap the default value with a placeholder. Defaults to 'unwrap'.

'unwrap'
Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def pop(
    self,
    key: str,
    default: Any = Undefined,
    *,
    default_mode: Literal['preserve', 'unwrap', 'wrap'] = 'unwrap',
) -> Any:
    """Pop the specified key if set and return its corresponding value.

    Args:
        key: The configuration key to pop the value for.
        default: The default value to return if the key is not set.
        default_mode: The default mode to use when returning a default
            value from the configuration dictionary. It can be either
            ``'preserve'`` to keep the default value as is, ``'unwrap'`` to
            unwrap the default value, or ``'wrap'`` to wrap the default
            value with a placeholder. Defaults to ``'unwrap'``.
    """
    if key not in self.__config_fields__:
        raise KeyError(
            f"Configuration key {key!r} cannot be popped as it is not "
            f"defined for wrapper {self.__class__.__qualname__!r}."
        )
    if key in self.__dict__:
        return self.__dict__.pop(key)
    if default is Undefined:
        return self.getdefault(key, mode=default_mode)
    if default_mode == 'wrap':
        return Default(default)
    if default_mode == 'unwrap':
        return get_value_or_default(default)
    return default

getdefault

getdefault(
    key: str,
    *,
    mode: Literal["preserve", "unwrap", "wrap"] = "unwrap",
) -> Any

Get the default value for the specified key.

Parameters:

Name Type Description Default
key str

The configuration key to get the default value for.

required
mode Literal['preserve', 'unwrap', 'wrap']

The mode to use when returning the default value. It can be either 'preserve' to keep the default value as is, 'unwrap' to unwrap the default value, or 'wrap' to wrap the default value with a placeholder. Defaults to 'unwrap'.

'unwrap'
Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def getdefault(
    self,
    key: str,
    *,
    mode: Literal['preserve', 'unwrap', 'wrap'] = 'unwrap',
) -> Any:
    """Get the default value for the specified key.

    Args:
        key: The configuration key to get the default value for.
        mode: The mode to use when returning the default value. It can be
            either ``'preserve'`` to keep the default value as is,
            ``'unwrap'`` to unwrap the default value, or ``'wrap'`` to wrap
            the default value with a placeholder. Defaults to ``'unwrap'``.
    """
    if key not in self.__config_fields__:
        raise KeyError(
            f"Default for configuration key {key!r} cannot be retrieved "
            f"as it is not defined for wrapper "
            f"{self.__class__.__qualname__!r}."
        )
    elif key in self.__config_defaults__:
        default = self.__config_defaults__[key]
    else:
        default = self.__config_fields__[key].get_default()

    if mode == 'wrap':
        return Default(default)
    if mode == 'unwrap':
        return get_value_or_default(default)
    return default

setdefault

setdefault(key: str, default: Any) -> Any

Set the default value for the specified key.

Parameters:

Name Type Description Default
key str

The configuration key to set the default value for.

required
default Any

The default value to set for the key.

required
Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def setdefault(self, key: str, default: Any) -> Any:
    """Set the default value for the specified key.

    Args:
        key: The configuration key to set the default value for.
        default: The default value to set for the key.
    """
    if key not in self.__config_fields__:
        raise KeyError(
            f"Default for configuration key {key!r} cannot be set as it "
            f"is not defined for wrapper {self.__class__.__qualname__!r}."
        )
    self.__config_defaults__[key] = default
    return default

update

update(
    *args: tuple[str, Any] | Mapping[str, Any],
    **kwargs: Any,
) -> None

Update the config dictionary with new data.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def update(
    self,
    *args: tuple[str, Any] | Mapping[str, Any],
    **kwargs: Any,
) -> None:
    """Update the config dictionary with new data."""
    # Helper function to update configuration entries
    def update_entry(key: str, value: Any) -> None:
        if key not in self.__config_fields__:
            raise KeyError(
                f"Configuration key {key!r} cannot be updated as it is "
                f"not defined for wrapper {self.__class__.__qualname__!r}."
            )
        setattr(self, key, value)

    # Update args data
    for arg in args:
        if isinstance(arg, tuple):
            if len(arg) != 2:
                raise ValueError(
                    f"Configuration update arguments must be provided as "
                    f"key-value pairs. Got: {arg}."
                )
            update_entry(arg[0], arg[1])
        else:
            for key, value in arg.items():
                update_entry(key, value)
    # Update kwargs data
    for key, value in kwargs.items():
        update_entry(key, value)

ConfigurableMeta

Bases: type

A metaclass for configurable classes.

collect_config_wrappers

collect_config_wrappers(
    bases: tuple[type, ...], namespace: dict[str, Any]
) -> list[ConfigType]

Collect configuration wrappers from the given bases and namespace.

It collects the configuration wrappers from the given bases and namespace by extracting the configuration wrapper type from the original bases annotation if it is a generic subclass of the configurable class or metaclass, and from the configuration attribute if present in the class and bases namespace.

Parameters:

Name Type Description Default
bases tuple[type, ...]

The class bases.

required
namespace dict[str, Any]

The class namespace.

required

Returns:

Type Description
list[ConfigType]

A list of configuration wrapper classes found in the given bases

list[ConfigType]

and namespace.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def collect_config_wrappers(
    cls, bases: tuple[type, ...], namespace: dict[str, Any], /,
) -> list[ConfigType]:
    """Collect configuration wrappers from the given bases and namespace.

    It collects the configuration wrappers from the given bases and
    namespace by extracting the configuration wrapper type from the
    original bases annotation if it is a generic subclass of the
    configurable class or metaclass, and from the configuration attribute
    if present in the class and bases namespace.

    Args:
        bases: The class bases.
        namespace: The class namespace.

    Returns:
        A list of configuration wrapper classes found in the given bases
        and namespace.
    """
    config_attr = getattr(cls, '__config_attr__', '__config__')
    config_wrappers: list[ConfigType] = []

    # The collection process is done in two steps to ensure that the
    # configuration attribute is extracted from the annotation first, and
    # then from the class and bases namespace.

    # Extract the configuration wrapper type from the annotation if it is a
    # generic subclass of the configurable class.
    meta_bases = get_meta_orig_bases(bases, namespace)
    for meta_base in meta_bases:
        origin = typing.get_origin(meta_base)
        if origin is None:
            continue
        if not isbaseclass_lenient(origin, 'Configurable'):
            continue
        args = typing.get_args(meta_base)
        if len(args) == 1:
            if isinstance(args[0], TypeVar):
                break
            if issubclass(args[0], ConfigWrapper):
                config_wrappers.append(args[0])
                break
        raise TypeError(
            f"Generic argument for the `Configurable` class must be a "
            f"subclass of the base configuration wrapper. Got: {args}."
        )

    # Extract the configuration wrapper type from the configuration
    # attribute if present in the class and bases namespace.
    meta_namespaces = get_meta_namespaces(bases, namespace)
    for meta_namespace in meta_namespaces:
        if config_attr not in meta_namespace:
            continue
        config_wrapper = meta_namespace[config_attr]
        if callable(config_wrapper):
            config_wrapper = config_wrapper()
        if isinstance(config_wrapper, ConfigWrapper):
            config_wrappers.append(config_wrapper.__class__)
            continue
        if isinstance(config_wrapper, dict):
            continue
        raise TypeError(
            f"Configuration attribute must be a dictionary or an "
            f"instance of the base configuration wrapper. Got: "
            f"{type(config_wrapper).__qualname__}."
        )

    return config_wrappers

Configurable

Bases: Generic[Config]

A base configurable class.

evaluate_config_field

evaluate_config_field(
    config: ConfigWrapper, /, name: str, *, parents: Any
) -> Any

Evaluate a configuration field from the provided sources.

It evaluates the configuration field from the provided configuration sources, which can be any object that has a configuration wrapper or a configuration dictionary. The evaluation is done by taking the first defined value from the sources (non default), where the first parent has the highest precedence.

Parameters:

Name Type Description Default
name str

The name of the field to evaluate.

required
config ConfigWrapper

The configuration object to evaluate the field from.

required
*parents Any

The parents to evaluate the field from. The first parent has the highest precedence.

required

Returns:

Type Description
Any

The evaluated configuration field.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def evaluate_config_field(
    config: ConfigWrapper, /, name: str, *, parents: Any
) -> Any:
    """Evaluate a configuration field from the provided sources.

    It evaluates the configuration field from the provided configuration
    sources, which can be any object that has a configuration wrapper or a
    configuration dictionary. The evaluation is done by taking the first
    defined value from the sources (non default), where the first parent has
    the highest precedence.

    Args:
        name: The name of the field to evaluate.
        config: The configuration object to evaluate the field from.
        *parents: The parents to evaluate the field from. The first parent
            has the highest precedence.

    Returns:
        The evaluated configuration field.
    """
    if name not in config.__config_fields__:
        raise KeyError(
            f"Configuration field {name!r} is not defined in the "
            f"configuration wrapper {config.__class__.__qualname__!r}."
        )
    values = [config.get(name, default_mode='wrap')]
    for parent in parents:
        if isinstance(parent, ConfigWrapper):
            values.append(parent.get(name, default_mode='wrap'))
        else:
            values.append(getattr(parent, name, Default()))
    return get_value_or_default(*values)

with_config

with_config(
    type_: Literal["model"],
    **kwargs: Unpack[ModelConfigDict],
) -> Callable[[type[Any]], ModelType]
with_config(
    type_: Literal["resource"],
    **kwargs: Unpack[ResourceConfigDict],
) -> Callable[[type[Any]], ResourceType]
with_config(
    type_: Literal["service"],
    **kwargs: Unpack[ServiceConfigDict],
) -> Callable[[type[Any]], ServiceType]
with_config(
    type_: Literal["model", "resource", "service"],
    **kwargs: Any,
) -> Callable[[type[Any]], type[Any]]

Decorator to apply configuration to a class.

It transforms the decorated class into the specified configuration class type and applies the provided configuration to the class.

Parameters:

Name Type Description Default
type_ Literal['model', 'resource', 'service']

The configuration type to apply. It can be one of: 'model', 'resource', or 'service'. This determines both the type of class to create and the type of configuration to apply.

required
**kwargs Any

The keyword arguments to pass to the configuration instance.

{}

Returns:

Type Description
Callable[[type[Any]], type[Any]]

A decorator to apply the configuration to the class.

Raises:

Type Description
NotImplementedError

If the configuration type is not supported.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/config.py
def with_config(
    type_: Literal['model', 'resource', 'service'],
    **kwargs: Any,
) -> Callable[[type[Any]], type[Any]]:
    """Decorator to apply configuration to a class.

    It transforms the decorated class into the specified configuration class
    type and applies the provided configuration to the class.

    Args:
        type_: The configuration type to apply. It can be one of: ``'model'``,
            ``'resource'``, or ``'service'``. This determines both the type of
            class to create and the type of configuration to apply.
        **kwargs: The keyword arguments to pass to the configuration instance.

    Returns:
        A decorator to apply the configuration to the class.

    Raises:
        NotImplementedError: If the configuration type is not supported.
    """

    def decorator(cls: type[Any]) -> type[Any]:
        # Validate configuration type
        config: ConfigWrapper
        config_type: type[Configurable[Any]]

        match type_:
            case 'model':
                from .schema.models import BaseModel, ModelConfig
                config = ModelConfig(**kwargs)
                config_type = BaseModel
            case 'resource':
                from .resources import BaseResource, ResourceConfig
                config = ResourceConfig(**kwargs)
                config_type = BaseResource
            case 'service':
                from .services import BaseService, ServiceConfig
                config = ServiceConfig(**kwargs)
                config_type = BaseService
            case _:
                raise NotImplementedError(
                    f"Unsupported configuration type: '{type_}'."
                )

        # FUTURE: Add support for configuration decorator style
        raise NotImplementedError('Not implemented yet...')

    return decorator