Skip to content

services

Service

Bases: ABC

Abstract base class for all services in the application.

This may be needed in the future to ensure a common interface.

ServiceSettings

Bases: BaseSettings, ABC

Base class for service settings with YAML configuration support.

This class provides automatic YAML configuration loading using pydantic-settings. The configuration is loaded from files defined in KNOWN_CONFIG_FILES and, optionally, from an in-memory document installed via :func:set_clabe_yml or :func:override_clabe_yml. The in-memory document ranks right after ./local/clabe.yml.

Attributes:

Name Type Description
__yml_section__ str | None

Optional class variable to override the config section name

Example
# Define a settings class
class MyServiceSettings(ServiceSettings):
    __yml_section__: ClassVar[str] = "my_service"

    host: str = "localhost"
    port: int = 8080
    enabled: bool = True

# Usage will automatically load from YAML files
settings = MyServiceSettings()

settings_customise_sources classmethod

settings_customise_sources(
    settings_cls: type[BaseSettings],
    init_settings: PydanticBaseSettingsSource,
    env_settings: PydanticBaseSettingsSource,
    dotenv_settings: PydanticBaseSettingsSource,
    file_secret_settings: PydanticBaseSettingsSource,
) -> tuple[PydanticBaseSettingsSource, ...]

Customizes the settings sources to include the safe YAML settings source.

Parameters:

Name Type Description Default
settings_cls type[BaseSettings]

The settings class

required
init_settings PydanticBaseSettingsSource

The initial settings source

required
env_settings PydanticBaseSettingsSource

The environment settings source

required
dotenv_settings PydanticBaseSettingsSource

The dotenv settings source

required
file_secret_settings PydanticBaseSettingsSource

The file secret settings source

required

Returns:

Type Description
tuple[PydanticBaseSettingsSource, ...]

Tuple[PydanticBaseSettingsSource, ...]: A tuple of settings sources

Source code in src/clabe/services.py
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
@classmethod
def settings_customise_sources(
    cls,
    settings_cls: type[ps.BaseSettings],
    init_settings: ps.PydanticBaseSettingsSource,
    env_settings: ps.PydanticBaseSettingsSource,
    dotenv_settings: ps.PydanticBaseSettingsSource,
    file_secret_settings: ps.PydanticBaseSettingsSource,
) -> tuple[ps.PydanticBaseSettingsSource, ...]:
    """
    Customizes the settings sources to include the safe YAML settings source.

    Args:
        settings_cls: The settings class
        init_settings: The initial settings source
        env_settings: The environment settings source
        dotenv_settings: The dotenv settings source
        file_secret_settings: The file secret settings source

    Returns:
        Tuple[PydanticBaseSettingsSource, ...]: A tuple of settings sources
    """
    yaml_sources = [
        _SafeYamlSettingsSource(settings_cls, yaml_file=p, yaml_config_section=cls.__yml_section__)
        for p in KNOWN_CONFIG_FILES
    ]
    # The in-memory document ranks right after the first (local override) config file
    return (
        init_settings,
        *yaml_sources[:1],
        _InMemorySettingsSource(settings_cls, config_section=cls.__yml_section__),
        *yaml_sources[1:],
        env_settings,
        dotenv_settings,
        file_secret_settings,
    )

set_clabe_yml

set_clabe_yml(config: Mapping[str, Any] | None) -> None

Installs a process-wide, in-memory configuration document.

The document has the same shape as a clabe.yml file (top-level keys are __yml_section__ names) and is consulted by every :class:ServiceSettings subclass constructed afterwards. It takes priority over all known config files except ./local/clabe.yml. Settings objects created before this call are not affected.

Parameters:

Name Type Description Default
config Mapping[str, Any] | None

The configuration document, e.g. fetched from a database. None clears it.

required

Raises:

Type Description
TypeError

If config is not a mapping, e.g. a path or raw YAML text.

Example
set_clabe_yml(fetch_clabe_config_from_db())
settings = MyServiceSettings()  # reads the "my_service" section of the in-memory document
Source code in src/clabe/services.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
def set_clabe_yml(config: t.Mapping[str, t.Any] | None) -> None:
    """
    Installs a process-wide, in-memory configuration document.

    The document has the same shape as a clabe.yml file (top-level keys are ``__yml_section__`` names) and is
    consulted by every :class:`ServiceSettings` subclass constructed afterwards. It takes priority over all
    known config files except ``./local/clabe.yml``. Settings objects created before this call are not affected.

    Args:
        config: The configuration document, e.g. fetched from a database. ``None`` clears it.

    Raises:
        TypeError: If ``config`` is not a mapping, e.g. a path or raw YAML text.

    Example:
        ```python
        set_clabe_yml(fetch_clabe_config_from_db())
        settings = MyServiceSettings()  # reads the "my_service" section of the in-memory document
        ```
    """
    global _global_config
    _global_config = _as_document(config)

override_clabe_yml

override_clabe_yml(
    config: Mapping[str, Any] | None,
) -> Iterator[None]

Temporarily overrides the in-memory configuration document for the current context.

While active, the given document replaces the one installed by :func:set_clabe_yml. Passing None disables the in-memory document inside the block. The override is scoped with a ContextVar, so it does not leak across threads or asyncio tasks.

Parameters:

Name Type Description Default
config Mapping[str, Any] | None

The configuration document to use inside the block.

required
Example
with override_clabe_yml({"my_service": {"port": 9090}}):
    settings = MyServiceSettings()
Source code in src/clabe/services.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
@contextlib.contextmanager
def override_clabe_yml(config: t.Mapping[str, t.Any] | None) -> t.Iterator[None]:
    """
    Temporarily overrides the in-memory configuration document for the current context.

    While active, the given document replaces the one installed by :func:`set_clabe_yml`. Passing ``None``
    disables the in-memory document inside the block. The override is scoped with a ``ContextVar``, so it
    does not leak across threads or asyncio tasks.

    Args:
        config: The configuration document to use inside the block.

    Example:
        ```python
        with override_clabe_yml({"my_service": {"port": 9090}}):
            settings = MyServiceSettings()
        ```
    """
    document = _as_document(config)
    token = _context_config.set(document if document is not None else _NO_CONFIG)
    try:
        yield
    finally:
        _context_config.reset(token)

get_clabe_yml

get_clabe_yml() -> Mapping[str, Any] | None

Returns the active in-memory configuration document, if any.

A document set via :func:override_clabe_yml takes precedence over the one set via :func:set_clabe_yml.

Returns:

Type Description
Mapping[str, Any] | None

The active configuration document, or None if none is installed.

Source code in src/clabe/services.py
73
74
75
76
77
78
79
80
81
82
83
84
85
def get_clabe_yml() -> t.Mapping[str, t.Any] | None:
    """
    Returns the active in-memory configuration document, if any.

    A document set via :func:`override_clabe_yml` takes precedence over the one set via :func:`set_clabe_yml`.

    Returns:
        The active configuration document, or ``None`` if none is installed.
    """
    ctx = _context_config.get()
    if ctx is _NO_CONFIG:
        return None
    return ctx if ctx is not None else _global_config