A modern configuration manager for Python with layered overrides and CLI.
Project description
Confixer ๐ง
A modern configuration manager for Python that unifies multi-source configs (YAML, JSON, TOML, .env, environment variables, CLI args, runtime overrides) into a single validated, dot-accessible object.
โจ Features
- ๐ Multi-format loading - YAML, JSON, TOML, .env files, and environment variables
- ๐ Layered overrides -
base config โ env vars โ CLI args โ runtimewith deep merge - ๐ฏ Dot-notation access -
config.database.hostinstead ofconfig["database"]["host"] - โ Schema validation - Pydantic models and dataclasses support
- ๐ ๏ธ CLI tool - Initialize, show, and validate configurations
- ๐ชข Environment nesting -
DB__HOST=localhostbecomes{"DB": {"HOST": "localhost"}} - ๐ Type coercion - Automatic conversion of strings to bool/int/float/None
๐ Quick Start
Installation
pip install confixer
Basic Usage
from confixer import Loader, YamlSource, EnvSource
# Create loader with multiple sources (layered overrides)
loader = Loader([
YamlSource("config.yaml"), # Base configuration
EnvSource(prefix="APP_") # Environment overrides
])
# Load and merge all sources
config = loader.load()
# Access with dot notation
print(config.database.host) # "localhost"
print(config.api.port) # 8080
# Still works like a dictionary
print(config["database"]["host"]) # "localhost"
๐ Full Documentation
Configuration Sources
YAML Source
from confixer import YamlSource
source = YamlSource("config.yaml")
data = source.load()
JSON Source
from confixer import JsonSource
source = JsonSource("config.json")
data = source.load()
TOML Source
from confixer import TomlSource
source = TomlSource("config.toml")
data = source.load()
Environment Source
from confixer import EnvSource
# Load from environment variables
env_source = EnvSource()
# Load from .env file
env_source = EnvSource(path=".env")
# Filter by prefix (APP_DEBUG โ DEBUG)
env_source = EnvSource(prefix="APP_")
# Nested environment variables
# DB__HOST=localhost โ {"DB": {"HOST": "localhost"}}
# DB__PORT=5432 โ {"DB": {"PORT": 5432}}
Layered Configuration
from confixer import Loader, YamlSource, EnvSource
# Sources are merged in order: base โ overrides
loader = Loader([
YamlSource("config.yaml"), # Base config
YamlSource("config.local.yaml"), # Local overrides
EnvSource(path=".env"), # Environment file
EnvSource(prefix="APP_"), # Environment variables
])
config = loader.load()
Environment Variable Nesting & Type Coercion
# Environment variables
export DB__HOST=localhost
export DB__PORT=5432
export DB__ENABLED=true
export DB__TIMEOUT=30.5
export DB__PASSWORD=secret123
from confixer import EnvSource
source = EnvSource()
config = source.load()
print(config.DB.HOST) # "localhost" (string)
print(config.DB.PORT) # 5432 (int)
print(config.DB.ENABLED) # True (bool)
print(config.DB.TIMEOUT) # 30.5 (float)
print(config.DB.PASSWORD) # "secret123" (string)
Type Coercion Rules:
- Booleans:
true,yes,1,onโTrue|false,no,0,offโFalse - Numbers:
123โ123(int) |123.45โ123.45(float) - None:
null,none,nilโNone - Strings: Everything else remains as string
Schema Validation
With Pydantic
from pydantic import BaseModel
from confixer import Loader, YamlSource, validate_with_schema
class DatabaseConfig(BaseModel):
host: str = "localhost"
port: int = 5432
name: str
user: str
class AppConfig(BaseModel):
debug: bool = False
database: DatabaseConfig
# Load and validate
loader = Loader([YamlSource("config.yaml")])
config_data = loader.load()
# Validate with schema
validated = validate_with_schema(dict(config_data), "myapp.models:AppConfig")
print(validated.database.host)
With Dataclasses
from dataclasses import dataclass
from confixer import validate_with_schema
@dataclass
class AppConfig:
name: str
debug: bool = False
port: int = 8000
# Validate
config_data = {"name": "MyApp", "debug": True}
validated = validate_with_schema(config_data, "__main__:AppConfig")
๐ ๏ธ CLI Tool
The confixer CLI provides commands to initialize, show, and validate configurations.
Initialize Configuration
# Create example YAML config
confixer init --format yaml --output config
# Create JSON config
confixer init --format json --output settings
# Create TOML config
confixer init --format toml --output app
Show Merged Configuration
# Show merged config from YAML + environment
confixer show config.yaml
# With .env file
confixer show config.yaml --env .env
# With environment variable prefix
confixer show config.yaml --prefix APP_
# Show specific nested path
confixer show config.yaml --path database.host
# Runtime overrides
confixer show config.yaml --set database.port=5433 --set app.debug=true
# Output as YAML
confixer show config.yaml --format yaml
Validate Configuration
# Basic syntax validation
confixer validate config.yaml
# Schema validation
confixer validate config.yaml --schema myapp.config:AppConfig
๐ Example Files
config.yaml
app:
name: "MyApp"
version: "1.0.0"
debug: false
database:
host: "localhost"
port: 5432
name: "myapp"
user: "admin"
api:
host: "0.0.0.0"
port: 8000
workers: 4
.env
# Override database settings
DB__HOST=prod-db.example.com
DB__PORT=5432
DB__PASSWORD=secret123
# Override API settings
API__HOST=0.0.0.0
API__PORT=8080
API__DEBUG=true
# App settings
APP__ENVIRONMENT=production
APP__LOG_LEVEL=INFO
Usage Example
from confixer import Loader, YamlSource, EnvSource
# Load with environment overrides
loader = Loader([
YamlSource("config.yaml"), # Base: DB host = localhost
EnvSource(path=".env") # Override: DB host = prod-db.example.com
])
config = loader.load()
print(config.database.host) # "prod-db.example.com" (from .env)
print(config.database.port) # 5432 (from .env, coerced to int)
print(config.api.debug) # True (from .env, coerced to bool)
print(config.app.name) # "MyApp" (from YAML, not overridden)
๐๏ธ Architecture
confixer/
โโ merge.py # deep_merge() for layered configs
โโ accessor.py # DotConfig class (dot notation)
โโ loader.py # Main Loader class
โโ schema.py # Validation (Pydantic/dataclasses)
โโ cli.py # CLI commands (Typer)
โโ sources/
โโ base.py # ConfigSource interface
โโ yaml_source.py
โโ json_source.py
โโ toml_source.py
โโ env_source.py # Environment + .env + nesting
๐ Configuration Flow
- Load - Each source loads its data into a dict
- Merge - Deep merge all sources in order (later overrides earlier)
- Wrap - Wrap result in
DotConfigfor dot-notation access - Validate - Optional schema validation with Pydantic/dataclasses
- Access - Use
config.key.subkeyorconfig["key"]["subkey"]
๐ค Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make changes and add tests
- Run tests:
pytest - Run pre-commit:
pre-commit run --all-files - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- Built with Typer for the CLI
- Pydantic for validation
- PyYAML, tomli, python-dotenv for format support
Confixer - Making configuration management simple, layered, and type-safe! ๐ง
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file confixer-0.1.0.tar.gz.
File metadata
- Download URL: confixer-0.1.0.tar.gz
- Upload date:
- Size: 16.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ccca7f262aaa18fb6945afa09adb445eec1c30a70357768bc821e4d6cd0e5f96
|
|
| MD5 |
51d6165e75367e4391cd6c129063fd9c
|
|
| BLAKE2b-256 |
ee94e64b05bd882335a17249a0edd56cc0e4b8c41a4ee90ce8a534d612555903
|
File details
Details for the file confixer-0.1.0-py3-none-any.whl.
File metadata
- Download URL: confixer-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2ffb1849d01ee0df4eab65dec7ad460f7cb19740e1f5fd90199e88e3c920d02
|
|
| MD5 |
38aaef87727b6afc53663fd464abdea9
|
|
| BLAKE2b-256 |
c654a478b519b526eac7b6512d6df211250526006565fcce404c968d27aed80b
|