# Environment and File Sources

Load configuration from environment variables, .env files, and various configuration file formats including JSON, YAML, TOML, and Docker/Kubernetes secrets. These sources provide flexible configuration management for different deployment environments and use cases.

## Capabilities

### Environment Variables Source

Load settings from environment variables with support for prefixes, nested structures, and type conversion.

```python { .api }
class EnvSettingsSource(PydanticBaseEnvSettingsSource):
    """Source for environment variables."""
    
    def __init__(
        self,
        settings_cls: type[BaseSettings],
        case_sensitive: bool | None = None,
        env_prefix: str | None = None,
        env_nested_delimiter: str | None = None,
        env_nested_max_split: int | None = None,
        env_ignore_empty: bool | None = None,
        env_parse_none_str: str | None = None,
        env_parse_enums: bool | None = None,
    ):
        """
        Initialize environment settings source.
        
        Parameters:
        - settings_cls: The settings class
        - case_sensitive: Whether environment variable names are case-sensitive
        - env_prefix: Prefix for environment variable names
        - env_nested_delimiter: Delimiter for nested environment variables
        - env_nested_max_split: Maximum splits for nested variables
        - env_ignore_empty: Whether to ignore empty environment variables
        - env_parse_none_str: String value to parse as None
        - env_parse_enums: Whether to parse enum field names to values
        """
```

### DotEnv File Source

Load settings from .env files with support for multiple files, encodings, and environment variable processing.

```python { .api }
class DotEnvSettingsSource(EnvSettingsSource):
    """Source for .env file loading."""
    
    def __init__(
        self,
        settings_cls: type[BaseSettings],
        env_file: DotenvType | None = ENV_FILE_SENTINEL,
        env_file_encoding: str | None = None,
        case_sensitive: bool | None = None,
        env_prefix: str | None = None,
        env_nested_delimiter: str | None = None,
        env_nested_max_split: int | None = None,
        env_ignore_empty: bool | None = None,
        env_parse_none_str: str | None = None,
        env_parse_enums: bool | None = None,
    ):
        """
        Initialize .env file settings source.
        
        Parameters:
        - settings_cls: The settings class
        - env_file: Path(s) to .env file(s) to load
        - env_file_encoding: Encoding for .env files
        - Other parameters: Same as EnvSettingsSource
        """

def read_env_file(
    file_path: Path,
    *,
    encoding: str | None = None,
    case_sensitive: bool = False,
    ignore_empty: bool = False,
    parse_none_str: str | None = None,
) -> Mapping[str, str | None]:
    """
    Read and parse environment files.
    
    Note: This function is deprecated and will be removed in the next version.
    Use DotEnvSettingsSource._static_read_env_file if needed.
    
    Parameters:
    - file_path: Path to environment file
    - encoding: File encoding
    - case_sensitive: Whether keys are case-sensitive
    - ignore_empty: Whether to ignore empty values
    - parse_none_str: String value to parse as None
    
    Returns:
    Mapping of environment variables
    """
```

### JSON Configuration Source

Load settings from JSON configuration files with support for nested structures and file encoding options.

```python { .api }
class JsonConfigSettingsSource(InitSettingsSource, ConfigFileSourceMixin):
    """Source for JSON configuration files."""
    
    def __init__(
        self,
        settings_cls: type[BaseSettings],
        json_file: PathType | None = None,
        json_file_encoding: str | None = None,
    ):
        """
        Initialize JSON configuration source.
        
        Parameters:
        - settings_cls: The settings class
        - json_file: Path to JSON configuration file
        - json_file_encoding: Encoding for JSON file
        """
```

### YAML Configuration Source

Load settings from YAML configuration files with support for configuration sections and file encoding.

```python { .api }
class YamlConfigSettingsSource(InitSettingsSource, ConfigFileSourceMixin):
    """Source for YAML configuration files."""
    
    def __init__(
        self,
        settings_cls: type[BaseSettings],
        yaml_file: PathType | None = None,
        yaml_file_encoding: str | None = None,
        yaml_config_section: str | None = None,
    ):
        """
        Initialize YAML configuration source.
        
        Parameters:
        - settings_cls: The settings class
        - yaml_file: Path to YAML configuration file
        - yaml_file_encoding: Encoding for YAML file
        - yaml_config_section: Top-level key to load from YAML file
        """
```

### TOML Configuration Source

Load settings from TOML configuration files with support for table headers and nested structures.

```python { .api }
class TomlConfigSettingsSource(InitSettingsSource, ConfigFileSourceMixin):
    """Source for TOML configuration files."""
    
    def __init__(
        self,
        settings_cls: type[BaseSettings],
        toml_file: PathType | None = None,
    ):
        """
        Initialize TOML configuration source.
        
        Parameters:
        - settings_cls: The settings class
        - toml_file: Path to TOML configuration file
        """

class PyprojectTomlConfigSettingsSource(TomlConfigSettingsSource):
    """Source for pyproject.toml configuration files."""
    
    def __init__(
        self,
        settings_cls: type[BaseSettings],
        pyproject_toml_depth: int = 0,
        pyproject_toml_table_header: tuple[str, ...] = (),
    ):
        """
        Initialize pyproject.toml configuration source.
        
        Parameters:
        - settings_cls: The settings class
        - pyproject_toml_depth: Directory levels up to search for pyproject.toml
        - pyproject_toml_table_header: TOML table header path
        """
```

### Secrets File Source

Load settings from Docker/Kubernetes secrets files with support for secrets directories and file-based configuration.

```python { .api }
class SecretsSettingsSource(PydanticBaseEnvSettingsSource):
    """Source for Docker/Kubernetes secrets files."""
    
    def __init__(
        self,
        settings_cls: type[BaseSettings],
        secrets_dir: PathType | None = None,
        case_sensitive: bool | None = None,
        env_prefix: str | None = None,
    ):
        """
        Initialize secrets file source.
        
        Parameters:
        - settings_cls: The settings class
        - secrets_dir: Directory containing secret files
        - case_sensitive: Whether secret names are case-sensitive
        - env_prefix: Prefix for secret names
        """
```

## Usage Examples

### Environment Variables

```python
import os
from pydantic_settings import BaseSettings

class AppSettings(BaseSettings):
    app_name: str = "MyApp"
    debug: bool = False
    max_connections: int = 100
    
    model_config = SettingsConfigDict(
        env_prefix='MYAPP_',
        case_sensitive=False
    )

# Set environment variables
os.environ['MYAPP_DEBUG'] = 'true'
os.environ['MYAPP_MAX_CONNECTIONS'] = '200'

settings = AppSettings()
print(f"Debug: {settings.debug}, Connections: {settings.max_connections}")
```

### Nested Environment Variables

```python
from pydantic import BaseModel

class DatabaseConfig(BaseModel):
    host: str = "localhost"
    port: int = 5432
    credentials: dict[str, str] = {}

class AppSettings(BaseSettings):
    database: DatabaseConfig = DatabaseConfig()
    
    model_config = SettingsConfigDict(
        env_nested_delimiter='__',
        case_sensitive=False
    )

# Environment variables: DATABASE__HOST, DATABASE__PORT, DATABASE__CREDENTIALS__USERNAME
os.environ['DATABASE__HOST'] = 'prod-db.company.com'
os.environ['DATABASE__PORT'] = '5432'
os.environ['DATABASE__CREDENTIALS__USERNAME'] = 'app_user'

settings = AppSettings()
```

### DotEnv Files

```python
# .env file content:
# DEBUG=true
# DATABASE_URL=postgresql://localhost/myapp
# API_KEY=secret-key-here

class AppSettings(BaseSettings):
    debug: bool = False
    database_url: str
    api_key: str
    
    model_config = SettingsConfigDict(
        env_file='.env',
        env_file_encoding='utf-8'
    )

settings = AppSettings()  # Loads from .env file
```

### Multiple DotEnv Files

```python
class AppSettings(BaseSettings):
    debug: bool = False
    database_url: str
    api_key: str
    
    model_config = SettingsConfigDict(
        env_file=['.env', '.env.local', '.env.production'],
        env_file_encoding='utf-8'
    )

# Files loaded in order, later files override earlier ones
settings = AppSettings()
```

### JSON Configuration

```python
# config.json:
# {
#   "app_name": "Production App",
#   "database": {
#     "host": "prod-db.company.com",
#     "port": 5432
#   },
#   "features": {
#     "enable_logging": true,
#     "max_retries": 3
#   }
# }

from pydantic import BaseModel

class DatabaseConfig(BaseModel):
    host: str
    port: int

class FeatureConfig(BaseModel):
    enable_logging: bool
    max_retries: int

class AppSettings(BaseSettings):
    app_name: str
    database: DatabaseConfig
    features: FeatureConfig
    
    model_config = SettingsConfigDict(
        json_file='config.json',
        json_file_encoding='utf-8'
    )

settings = AppSettings()
```

### YAML Configuration

```python
# config.yaml:
# production:
#   app_name: "Production App"
#   database:
#     host: "prod-db.company.com"
#     port: 5432
#   api:
#     timeout: 30
#     retries: 3

class AppSettings(BaseSettings):
    app_name: str
    database: dict
    api: dict
    
    model_config = SettingsConfigDict(
        yaml_file='config.yaml',
        yaml_config_section='production'  # Load from 'production' section
    )

settings = AppSettings()
```

### Docker Secrets

```python
# Docker secrets mounted at /run/secrets/
# Files: /run/secrets/db_password, /run/secrets/api_key

class AppSettings(BaseSettings):
    db_password: str
    api_key: str
    
    model_config = SettingsConfigDict(
        secrets_dir='/run/secrets'
    )

settings = AppSettings()  # Loads secrets from files
```

### Custom Source with Multiple Files

```python
from pydantic_settings import JsonConfigSettingsSource, YamlConfigSettingsSource

class AppSettings(BaseSettings):
    app_name: str = "MyApp"
    debug: bool = False
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            JsonConfigSettingsSource(settings_cls, json_file='config.json'),
            YamlConfigSettingsSource(settings_cls, yaml_file='config.yaml'),
            env_settings,
            dotenv_settings,
            file_secret_settings,
        )

settings = AppSettings()  # Loads from JSON, YAML, env vars, .env, and secrets
```