Skip to main content

Extra sources for pydantic-settings with environment variable substitution for YAML and TOML files

Project description

pydantic-settings-extra-sources

Extra configuration sources for pydantic-settings that enable loading settings from YAML and TOML files with environment variable substitution.

Features

  • YAML and TOML Support: Load configuration from YAML and TOML files
  • Environment Variable Substitution: Reference environment variables directly in config files using ${ENV_VAR} syntax
  • Default Values: Provide fallback values with ${ENV_VAR:-default_value} syntax
  • Complex Type Support: Handles strings, integers, floats, booleans, lists, dictionaries, and nested structures
  • Directory Merging: Load and merge multiple config files from a directory
  • Type-Safe: Full integration with Pydantic's validation and type checking

Installation

poetry add pydantic-settings-extra-sources

Quick Start

1. Create a YAML config file

# config.yaml
database:
  host: ${DB_HOST:-localhost}
  port: ${DB_PORT:-5432}
  name: ${DB_NAME}
api_key: ${API_KEY}
debug: ${DEBUG:-false}

2. Define your settings model

from pydantic import Field
from pydantic_settings import SettingsConfigDict
from pydantic_settings_sources import YamlEnvSettings

class Settings(YamlEnvSettings):
    model_config = SettingsConfigDict(
        yaml_file="config.yaml",
        extra="allow",
        case_sensitive=False,
    )

    database: dict
    api_key: str
    debug: bool = False

# Load settings - environment variables will be substituted
settings = Settings()

3. Set environment variables and run

export DB_NAME=myapp
export API_KEY=secret123
python app.py

Usage

Simple Inheritance (Recommended)

YAML:

from pydantic_settings import SettingsConfigDict
from pydantic_settings_sources import YamlEnvSettings

class Settings(YamlEnvSettings):
    model_config = SettingsConfigDict(
        yaml_file="config.yaml",  # Path to YAML file or directory
        yaml_file_encoding="utf-8",  # Optional, defaults to utf-8
        extra="allow",  # Optional: allow extra fields from YAML
        case_sensitive=False,  # Optional: case-insensitive field matching
    )

    # Your fields here
    database_url: str
    debug: bool = False

TOML:

from pydantic_settings import SettingsConfigDict
from pydantic_settings_sources import TomlEnvSettings

class Settings(TomlEnvSettings):
    model_config = SettingsConfigDict(
        toml_file="config.toml",  # Path to TOML file or directory
        toml_file_encoding="utf-8",  # Optional, defaults to utf-8
        extra="allow",  # Optional: allow extra fields from TOML
        case_sensitive=False,  # Optional: case-insensitive field matching
    )

    # Your fields here
    database_url: str
    debug: bool = False

Advanced: Manual Source Configuration

If you need more control over the settings sources order:

from pydantic_settings import BaseSettings
from pydantic_settings_sources import YamlEnvConfigSettingsSource

class Settings(BaseSettings):
    database_url: str
    debug: bool = False

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            YamlEnvConfigSettingsSource(
                cls,
                yaml_file="config.yaml",
                yaml_file_encoding="utf-8"
            ),
            env_settings,
            dotenv_settings,
            file_secret_settings,
        )

Environment Variable Syntax

Required variable:

api_key: ${API_KEY}  # Throws MissingEnvVarError if API_KEY not set

With default value:

host: ${HOST:-localhost}  # Uses "localhost" if HOST not set
port: ${PORT:-8080}       # Uses "8080" if PORT not set

Complex Types

Environment variables containing JSON are automatically parsed:

# Set complex environment variables
export LIST_VALUE='["item1", "item2", "item3"]'
export DICT_VALUE='{"key1": "value1", "key2": "value2"}'
export NESTED_VALUE='{"level1": {"level2": {"key": "value"}}}'
# config.yaml
items: ${LIST_VALUE}
mapping: ${DICT_VALUE}
nested: ${NESTED_VALUE}

Loading from Directories

When pointing to a directory, all .yaml/.yml or .toml files are loaded and deep-merged:

YamlEnvConfigSettingsSource(
    settings_cls,
    yaml_file="./config",  # Directory path
    yaml_file_encoding="utf-8"
)

Files are processed in alphabetical order, with later files overriding earlier ones.

Error Handling

from pydantic_settings_extra_sources.errors import MissingEnvVarError, ConfigFileParsingError

try:
    settings = Settings()
except MissingEnvVarError as e:
    print(f"Missing required environment variable: {e}")
except ConfigFileParsingError as e:
    print(f"Failed to parse config file: {e}")

How It Works

The library reads environment variables directly from your YAML/TOML configuration files by:

  1. Loading the config file(s)
  2. Finding all ${ENV_VAR} or ${ENV_VAR:-default} patterns
  3. Substituting them with values from os.environ
  4. Parsing JSON values for complex types
  5. Returning the resolved configuration to pydantic-settings

This approach keeps your configuration structure in files while allowing environment-specific values to be injected at runtime.

Development

See CLAUDE.md for development setup and commands.

License

See LICENCE file.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydantic_settings_extra_sources-0.1.0.tar.gz (5.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file pydantic_settings_extra_sources-0.1.0.tar.gz.

File metadata

File hashes

Hashes for pydantic_settings_extra_sources-0.1.0.tar.gz
Algorithm Hash digest
SHA256 45364f9f8d7366eb9778fc225e333f6c8176799baf75591f3dab65cec892976a
MD5 60a78d6a46266857036c7f4da575b050
BLAKE2b-256 8d8ed54a98961f0364d253a933a7b6c66fa68d387bdf91e52eb694e58781e859

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydantic_settings_extra_sources-0.1.0.tar.gz:

Publisher: publish.yml on lazytrot/pydantic-settings-extra-sources

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydantic_settings_extra_sources-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pydantic_settings_extra_sources-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fdcce7d34d8a3e03ffb10ad28578f763b7a412f1caa7734ce3e142e35f5a645c
MD5 cd4f6d68423afef97b3cdf3f19a3fd12
BLAKE2b-256 0bfc7928baf2a2531d2959279ef31865a176eda7200b67ef64801ba37e8ac187

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydantic_settings_extra_sources-0.1.0-py3-none-any.whl:

Publisher: publish.yml on lazytrot/pydantic-settings-extra-sources

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page