didactic-settings
didactic-settings composes a validated dx.Model from layered configuration:
a primary file and the config-group fragments its defaults: list selects, a
profile, overlay files, environment variables, dotenv files, command-line
arguments and dotted overrides. Every layer is checked against the schema at
every depth, tagged-union fields are descended into the variant their
discriminator selects, ${...} expressions are resolved against the composed
tree, and the instance records which layer wrote each leaf.
Install
pip install didactic-settings
pip install 'didactic-settings[yaml]'
JSON and TOML are read through the standard library; the yaml extra installs
PyYAML for .yaml and .yml files.
Compose a configuration
from typing import Literal
import didactic.api as dx
from didactic.settings import compose_traced
class OptimizerSpec(dx.TaggedUnion, discriminator="kind", extra="forbid"):
lr: float = 1e-3
class Adam(OptimizerSpec):
kind: Literal["adam"] = "adam"
betas: tuple[float, ...] = (0.9, 0.999)
class Sgd(OptimizerSpec):
kind: Literal["sgd"] = "sgd"
momentum: float = 0.9
class TrainerSpec(dx.Model, extra="forbid"):
epochs: int = 1
out_dir: str = "runs"
log_dir: str = "${.out_dir}/logs"
class RunSpec(dx.Model, extra="forbid"):
optimizer: OptimizerSpec = dx.field(default_factory=Adam)
trainer: TrainerSpec = dx.field(default_factory=TrainerSpec)
run = compose_traced(
"conf/run.yaml",
schema=RunSpec,
profile="dev",
overlays=["conf/big.toml"],
groups={"optimizer": "sgd"},
overrides=["optimizer.momentum=0.5", ("trainer.epochs", 3)],
)
run.value.trainer.log_dir
run.provenance["trainer.epochs"].label # "override:trainer.epochs=3"
run.provenance["optimizer.momentum"].label # "override:optimizer.momentum=0.5"
conf/run.yaml may carry a defaults: list selecting root fragments and
config-group fragments (optimizer: adam loads conf/optimizer/adam.yaml);
groups= replaces the file's choice for a slot; profile="dev" loads
conf/profiles/dev.yaml; an override whose key contains /
(model/type_encoder=lstm) selects a nested group and one without sets a
field, decoded by the leaf's annotation. A key the schema does not declare,
at any depth and in any layer, is refused with its dotted path and the layer
that set it, and so is a value of the wrong type.
Class-based settings
from didactic.settings import EnvSource, FileSource, Settings
class RunSettings(Settings, RunSpec):
__sources__ = (FileSource("local.toml"), EnvSource(prefix="APP_"))
settings = RunSettings.load("conf/run.yaml", profile="dev", trainer__epochs=3)
settings.__provenance__["trainer.epochs"].label
Settings.load() composes the primary file, its groups, the profile, overlays,
the declared sources and the overrides in that precedence. EnvSource reads
APP_TRAINER__EPOCHS for trainer.epochs and decodes the text by the field's
annotation; APP_OPTIMIZER='{"kind": "sgd"}' sets a whole slot.
| Source | Input |
|---|---|
EnvSource(prefix="APP_") |
environment variables |
DotEnvSource(path=".env", prefix="APP_") |
a dotenv file |
FileSource(path="config.toml") |
one JSON, TOML, or YAML document |
CliSource(args=namespace) |
an argparse.Namespace or mapping |
Because Settings extends dx.Model, the composed tree receives the same type
checks, axioms, field validators, and indexed-field checks as any other
Didactic model.
Documentation
See the settings guide for the composition ladder, config groups, union descent, interpolation and the resolver registry, and per-leaf provenance.
License
Released under the MIT License.
Metadata
Release files for didactic-settings 0.17.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 | |
|---|---|---|---|
| didactic_settings-0.17.0.tar.gz | 48.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| didactic_settings-0.17.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 106.9 kB
Release files / didactic_settings-0.17.0.tar.gz
| Download URL | didactic_settings-0.17.0.tar.gz |
|---|---|
| Size | 48.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b381204e2b00d58067e9eb1d9d205b6011a68e65ef596cd5b268c6375012a51
|
|
BLAKE2b-256 checksum How to use checksums |
2094352b43b09fc2f7d9a4dc3f1ed3ef7db262d641f984483884709ecbba4ace
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logRelease files / didactic_settings-0.17.0-py3-none-any.whl
| Download URL | didactic_settings-0.17.0-py3-none-any.whl |
|---|---|
| Size | 58.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fa41082e90789fbc6f92572a9216edf5ba23ea02013d0bb55641c1b9958667ee
|
|
BLAKE2b-256 checksum How to use checksums |
478bb749de5a9c3476b55b09e114496548e474c4aa2c75f2e4689a7b602122fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency log