saneconfig
Dead-simple typed config loader for dataclasses:
- defaults
- TOML file(s)
- environment variables
with great errors and provenance ("where did this value come from?").
Python 3.11+.
Core package has zero runtime dependencies; optional extras:
saneconfig[dotenv]for.envfile support.
Install
pip install saneconfig
# optional .env support
pip install "saneconfig[dotenv]"
Quick start
from dataclasses import dataclass
from saneconfig import load, REQUIRED
@dataclass
class AppConfig:
debug: bool = False
port: int = 8080
database_url: str = REQUIRED
cfg = load(
AppConfig,
env_prefix="APP",
files=["config.toml", "config.local.toml"],
)
print(cfg.port)
Precedence (highest wins)
- CLI args (
argv=Trueorargv=[...]) - Environment variables
.envfile values (whendotenvis enabled)- TOML files (later overrides earlier)
- Dataclass defaults
TOML example
debug = true
port = 9000
database_url = "postgresql://user:pass@localhost:5432/mydb"
Nested dataclasses map to TOML tables:
[db]
host = "localhost"
port = 5432
Env var mapping
With env_prefix="APP":
APP_PORT=9000->portAPP_DEBUG=true->debug- nested via
__:APP_DB__HOST=localhost->db.host
Booleans accept: true/false, yes/no, on/off, 1/0 (case-insensitive).
Lists in env vars use JSON:
APP_ALLOWED='["a","b"]'
CLI overrides
Enable CLI parsing by passing argv=True (uses sys.argv[1:]) or provide a list explicitly:
cfg = load(
AppConfig,
env_prefix="APP",
argv=["--port=9001", "--db.host=db.internal"],
)
Supported form: --key=value with dotted nesting (--db.host=x).
Provenance / debugging
cfg, report = load(
AppConfig,
env_prefix="APP",
files=["config.toml", "config.local.toml"],
return_report=True,
)
print(report)
Example output:
database_url='postgresql://...' (env:APP_DATABASE_URL)
debug=False (default)
port=9000 (file:config.toml)
Schema docs
You can include richer docs using dataclass metadata:
from dataclasses import dataclass, field
@dataclass
class AppConfig:
port: int = field(default=8080, metadata={"help": "HTTP listen port"})
from saneconfig import dump_schema
print(dump_schema(AppConfig, env_prefix="APP"))
dump_schema(...) includes a Help column using field(metadata={"help": ...}).
Errors that help
If a value cannot be converted:
ConfigError: port expected int but got "eighty"
source: env:APP_PORT
hint: Use a valid int value.
If required values are missing:
ConfigError: missing required configuration values:
- database_url
Supported types (v0.1)
str,int,float,boolOptional[T]list[T](TOML arrays or JSON arrays in env)Literal[...]- nested dataclasses
pathlib.Pathdict[str, T](TOML table or JSON object in env)
Non-goals (by design)
- profiles/composition systems
- interpolation DSLs
- frameworks and global state
MIT Licensed.
A tiny example you can run
from dataclasses import dataclass
from typing import Literal, Optional
from saneconfig import REQUIRED, load
@dataclass
class DB:
host: str = "localhost"
port: int = 5432
@dataclass
class App:
mode: Literal["dev", "prod"] = "dev"
debug: bool = False
port: int = 8080
api_key: str = REQUIRED
db: DB = DB()
notes: Optional[str] = None
cfg, report = load(App, env_prefix="APP", files=["config.toml"], return_report=True)
print(cfg)
print(report)
Metadata
Release files for saneconfig 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| saneconfig-0.1.0.tar.gz | 14.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| saneconfig-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.1 kB
Release files / saneconfig-0.1.0.tar.gz
| Download URL | saneconfig-0.1.0.tar.gz |
|---|---|
| Size | 14.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7ef26073be5317f419e9f865a08a55ff610bc6b2df1118ff1322c31bd77d4bcf
|
|
BLAKE2b-256 checksum How to use checksums |
d60f8c11ce6099d45eeccc93d98f6945197436008f4ca93279e0b93b128cee8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|
Release files / saneconfig-0.1.0-py3-none-any.whl
| Download URL | saneconfig-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d7a00796a800c1c94fd91116e10044ce68a057701ec2d5361ad6474fcdbc56a6
|
|
BLAKE2b-256 checksum How to use checksums |
44eef23d0c0f75375f9e10fb9fc60b78170349f90705ea225235c992b6fc70ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|