API Reference
April 18, 2026 · View on GitHub
Config
class Config(data: dict | None = None, *, metadata=None, prefix="")
Nested configuration container. Nested dicts are automatically wrapped into child Config instances.
Access
| Operation | Example |
|---|---|
| Attribute read | cfg.db.host |
| Dotted-path read | cfg["db.host"] |
| Attribute write | cfg.db.host = "x" |
| Dotted-path write | cfg["db.host"] = "x" |
| Containment | "db.host" in cfg |
| Delete | del cfg.db.host |
Methods
get(path, default=None)— safe dotted-path readkeys(),values(),items()— top-level iterationto_dict()— recursive plain-dict exportto_json(**kwargs)— JSON string; passes kwargs tojson.dumpsfreeze()— recursively freeze; raisesFrozenConfigErroron writeunfreeze()— recursively unfreezesnapshot()— push current state onto the snapshot stackrollback()— pop and restore the last snapshoton_change(callback)— registercallback(path, new_value, old_value)meta(path)— return{"source": str, "history": tuple}for a dotted pathmetadata()— return the full metadata dict
Properties
frozen—Trueif the config is currently frozen
Sources
All sources inherit from Source and expose a single method:
load() -> dict[str, Any]
DictSource
DictSource(data: dict, *, name: str = "")
Wraps an in-memory dict.
JsonFileSource
JsonFileSource(path: str | Path, *, name: str = "")
TomlFileSource
TomlFileSource(path: str | Path, *, name: str = "")
EnvSource
EnvSource(prefix: str = "", *, coerce: bool = True, environ: dict | None = None, name: str = "")
Reads environment variables and maps them to nested keys by splitting on _. prefix is stripped and not included in the output key.
CliSource
CliSource(args: list[str], *, coerce: bool = True, name: str = "")
Parses --key=value and --key value arguments. Dotted keys map to nested dicts.
Merge
merge()
merge(base: dict, override: dict, strategy: MergeStrategy = DEEP_MERGE) -> dict
Returns a new dict. Neither input is mutated.
MergeStrategy
class MergeStrategy(enum.Enum):
DEEP_MERGE = "deep_merge"
OVERRIDE = "override"
APPEND = "append"
ConfigLoader
ConfigLoader(sources: list[Source], strategy: MergeStrategy = DEEP_MERGE)
load() -> Config— merge all sources in order, attach metadata
ProfileLoader
ProfileLoader(base_sources: list[Source], profiles: dict[str, Source], strategy: MergeStrategy = DEEP_MERGE)
load(profile: str | None = None) -> Config— load base sources and optionally apply a named profile overlay
Validation
validate()
validate(
data: dict,
schema: type,
*,
apply_defaults: bool = False,
allow_extra: bool = True,
) -> dict
Raises ValidationError on type mismatch, missing required fields, or constraint failure.
Constraints
Range(min: float | None = None, max: float | None = None)
Length(min: int | None = None, max: int | None = None)
Pattern(pattern: str)
OneOf(*choices)
Attach via __constraints__ = {"field": [constraint, ...]} on the schema class.
Build
Build(registry: Registry)
typing.Annotated metadata marker. When validate() encounters
field: Annotated[T, Build(reg)], the raw value is passed through
reg.build(...) before the field's type is checked. Works on default
values too.
Registry
Registry(name: str, *, discriminator: str = "type")
String-tag → factory container. Generic: Registry[T]("name").
Registration
reg.register("silu", nn.SiLU) # direct
@reg("leaky_relu") # decorator
class MyLeakyReLU(nn.Module): ...
Keys are lowercased. Duplicate registration raises ValueError.
Access
reg.build(spec) -> T | None— resolve into an instance. Acceptsstr(short form),dictwith atypekey + kwargs (long form),None(pass-through), or an existing instance (idempotent).reg.get(name) -> type[T] | callable | None— return the registered factory/class without instantiating.Nonepass-through. For APIs that taketype[T]and construct later.reg.keys() -> list[str]— sorted list of registered keys."key" in reg— containment check (case-insensitive).
See the Registry guide for the full tutorial.
Concurrency
ThreadSafeConfig
ThreadSafeConfig(config: Config, lock: threading.RLock | None = None)
Wraps all reads and writes in the provided lock (or a new RLock). Exposes the same interface as Config.
FileLock
FileLock(path: str | Path)
Context manager. Acquires fcntl.LOCK_EX on entry, releases on exit.
acquire()/release()for manual management
interpolate()
interpolate(data: dict, environ: dict | None = None) -> dict
Resolves ${path.to.key} and ${env:VAR} placeholders. Raises CircularReferenceError on circular references.
Errors
All errors inherit from ConfigError.
| Exception | Raised when |
|---|---|
ConfigError | Base class |
FrozenConfigError | Writing to a frozen Config |
ValidationError | Schema validation fails |
CircularReferenceError | Interpolation detects a cycle |