Skip to content

forge.config

Typed, validated, layered configuration from environment variables, .env files, and TOML configuration files.

forge.config

Config module — layered configuration with pydantic-settings and TOML support.

Provides the ForgeConfig model with automatic environment-variable binding via pydantic-settings, the ConfigModule lifecycle wrapper, and utilities for loading TOML files, dotenv files, and deep merging.

Functions:

deep_merge

deep_merge(base: dict[str, Any], overlay: dict[str, Any]) -> dict[str, Any]

Alias for :func:merge_config.

Source code in src/forge/config/loaders.py
def deep_merge(base: dict[str, Any], overlay: dict[str, Any]) -> dict[str, Any]:
    """Alias for :func:`merge_config`."""
    return merge_config(base, overlay)

field_is_sensitive

field_is_sensitive(name: str) -> bool

Return True if name suggests it holds a secret value.

Source code in src/forge/config/secrets.py
def field_is_sensitive(name: str) -> bool:
    """Return ``True`` if *name* suggests it holds a secret value."""
    lowered = name.lower()
    sensitive_keywords = {"api_key", "api_secret", "password", "secret", "token", "auth"}
    return any(kw in lowered for kw in sensitive_keywords)

is_secret

is_secret(value: object) -> bool

Return True if value is or contains a secret.

Checks for SecretStr, SecretBytes, or any field name containing api_key, password, secret, token.

Source code in src/forge/config/secrets.py
def is_secret(value: object) -> bool:
    """
    Return ``True`` if *value* is or contains a secret.

    Checks for ``SecretStr``, ``SecretBytes``, or any field name
    containing ``api_key``, ``password``, ``secret``, ``token``.
    """
    return isinstance(value, PydanticSecretStr)

load_dotenv

load_dotenv(path: str | Path) -> dict[str, str]

Load a .env file and return key-value pairs.

Supports: - KEY=value - KEY="quoted value" - KEY='single quoted value' - # comments - Values containing = signs (e.g. connection strings)

Source code in src/forge/config/loaders.py
def load_dotenv(path: str | Path) -> dict[str, str]:
    """
    Load a ``.env`` file and return key-value pairs.

    Supports:
    - ``KEY=value``
    - ``KEY="quoted value"``
    - ``KEY='single quoted value'``
    - ``# comments``
    - Values containing ``=`` signs (e.g. connection strings)
    """
    path = Path(path)
    if not path.exists():
        return {}

    result: dict[str, str] = {}
    for raw_line in path.read_text(encoding="utf-8").splitlines():
        stripped = raw_line.strip()
        if not stripped or stripped.startswith("#"):
            continue

        if "=" not in stripped:
            continue

        key, _, raw_value = stripped.partition("=")
        key = key.strip()
        raw_value = raw_value.strip()

        if not key:
            continue

        # Strip surrounding quotes
        if len(raw_value) >= 2 and raw_value[0] == raw_value[-1] and raw_value[0] in ('"', "'"):  # noqa: PLR2004
            raw_value = raw_value[1:-1]

        result[key] = raw_value

    return result

load_toml

load_toml(path: str | Path) -> dict[str, Any]

Parse a TOML file and return its contents as a dict.

Raises

ConfigurationError If the file cannot be parsed or contains circular references.

Source code in src/forge/config/loaders.py
def load_toml(path: str | Path) -> dict[str, Any]:
    """
    Parse a TOML file and return its contents as a dict.

    Raises
    ------
    ConfigurationError
        If the file cannot be parsed or contains circular references.
    """
    path = Path(path)
    if not path.exists():
        return {}

    try:
        raw = path.read_bytes()
        data: dict[str, Any] = tomllib.loads(raw.decode("utf-8"))
    except tomllib.TOMLDecodeError as exc:
        from forge.core.exceptions import ConfigurationError

        raise ConfigurationError(f"Failed to parse TOML file '{path}': {exc}") from exc

    _resolve_env_vars(data, path)
    return data

mask_value

mask_value(value: str | SecretStr | None) -> str

Return a masked representation of value suitable for logging.

Actual secret values are never exposed in log output.

Source code in src/forge/config/secrets.py
def mask_value(value: str | PydanticSecretStr | None) -> str:
    """
    Return a masked representation of *value* suitable for logging.

    Actual secret values are never exposed in log output.
    """
    if value is None:
        return "<not set>"
    if isinstance(value, PydanticSecretStr):
        if not value.get_secret_value():
            return "<not set>"
        return MASK
    if not value:
        return "<not set>"
    return MASK

merge_config

merge_config(base: dict[str, Any], overlay: dict[str, Any]) -> dict[str, Any]

Deep-merge overlay into base, returning a new dict.

Later values win. Nested dicts are merged recursively; all other values are replaced.

Source code in src/forge/config/loaders.py
def merge_config(base: dict[str, Any], overlay: dict[str, Any]) -> dict[str, Any]:
    """
    Deep-merge *overlay* into *base*, returning a new dict.

    Later values win.  Nested dicts are merged recursively; all other
    values are replaced.
    """
    merged = dict(base)
    for key, value in overlay.items():
        if key in merged and isinstance(merged[key], dict) and isinstance(value, dict):
            merged[key] = merge_config(merged[key], value)
        else:
            merged[key] = value
    return merged

str_from_secret

str_from_secret(value: SecretStr | None) -> str | None

Extract the plain-text string from a SecretStr, or return None.

Source code in src/forge/config/secrets.py
def str_from_secret(value: PydanticSecretStr | None) -> str | None:
    """Extract the plain-text string from a ``SecretStr``, or return ``None``."""
    if value is None:
        return None
    return value.get_secret_value()