Metadata-Version: 2.4
Name: confocal
Version: 0.1.6
Summary: Multi-layer configuration management with source tracking
Project-URL: Homepage, https://github.com/joshuafcole/confocal
Project-URL: Repository, https://github.com/joshuafcole/confocal
Author-email: Your Name <your.email@example.com>
License: MIT
Requires-Python: >=3.8
Requires-Dist: pydantic-settings<2.14.0,>=2.13.0
Requires-Dist: pydantic<2.13.0,>=2.12.0
Requires-Dist: pyyaml>=6.0.0
Requires-Dist: rich>=13.0.0
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
Provides-Extra: dev
Requires-Dist: build>=0.10.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: twine>=4.0.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
Provides-Extra: test
Requires-Dist: pytest-cov>=4.1.0; extra == 'test'
Requires-Dist: pytest-env>=1.1.0; extra == 'test'
Requires-Dist: pytest>=7.4.0; extra == 'test'
Description-Content-Type: text/markdown

# Confocal

A multi-layer configuration management library built on pydantic with source tracking and profile support.

## Features

- Hierarchical config file discovery (searches parent directories)
- Profile support for different environments
- Full source tracking to explain where each config value came from
- Built on pydantic for robust validation and type safety
- Rich terminal output for config inspection

## Installation

```bash
pip install confocal
```

## Quick Start

```python
from confocal import BaseConfig
from pydantic import Field

class MyConfig(BaseConfig):
    database_url: str
    name: str = Field(default="Anonymous")
    debug: bool = False

# Load config from raiconfig.toml, environment variables, etc.
config = MyConfig.load()

# Show where config values came from
config.explain()
```

## Config Sources (in order of precedence)

1. Initialization arguments
2. Environment variables
3. Active profile from config file
4. Config files (YAML or TOML)
5. Default values

## Using Config Files

Confocal supports both TOML and YAML config files. Specify which format to use in your config class:

### Using TOML (default)
```python
class MyConfig(BaseConfig):
    model_config = SettingsConfigDict(
        toml_file="config.toml",
    )
```

### Using YAML
```python
class MyConfig(BaseConfig):
    model_config = SettingsConfigDict(
        yaml_file="config.yaml",
    )
```

## Using Profiles

Profile support works with both TOML and YAML files.

**TOML example** (`raiconfig.toml`):
```toml
database_url = "postgresql://prod-db:5432"

[profile.dev]
database_url = "postgresql://localhost:5432"
debug = true

[profile.test]
database_url = "postgresql://test-db:5432"
```

**YAML example** (`config.yaml`):
```yaml
database_url: "postgresql://prod-db:5432"

profile:
  dev:
    database_url: "postgresql://localhost:5432"
    debug: true
  test:
    database_url: "postgresql://test-db:5432"
```

Activate a profile:
```bash
export ACTIVE_PROFILE=dev
```

### YAML Environment Variables

YAML configs support environment variable substitution:

```yaml
database_url: "{{ env_var('DB_URL', 'postgresql://localhost:5432') }}"
api_key: "{{ env_var('API_KEY') }}"  # Required, will error if not set
```

## Advanced Usage

Show full config inheritance chain:
```python
config.explain(verbose=True)
```

Manually find nearest config file in parent directories:
```python
from confocal import find_upwards
config_path = find_upwards("config.toml")
```

## License

MIT
