Load a consumer package's config
Goal: give your package a typed config object backed by ~/.axm, with an
environment override for CI, in a few lines.
This is the pattern every axm-config consumer uses: declare a pydantic model,
call load, and let the resolver fill each field from env > file > default.
1. Declare a model
from pydantic import BaseModel
class FredConfig(BaseModel):
api_key: str # required — ConfigError if unresolved
timeout: int = 30 # optional — falls back to the model default
2. Load it under a namespace
from axm_config import load
cfg = load("research.fred", FredConfig)
print(cfg.api_key, cfg.timeout)
load resolves each field by name: it looks for api_key then timeout in the
research.fred namespace, walking env > file > default for each. A required
field with no value anywhere raises ConfigError.
3. Seed the file layer
writes [research.fred] into ~/.axm/config.toml (atomic, 0600).
4. Override in CI with an environment variable
An environment variable always wins over the file. The variable name is
AXM_<NS>_<KEY>, upper-cased, with each namespace dot folded to a double
underscore:
5. Diagnose an unexpected value
If a field resolves to something you did not expect, ask the doctor where it came from:
axm-config doctor research.fred
# research.fred.api_key: env <- the env var is shadowing the file
or over MCP / the axm CLI:
The doctor is read-only: it reports the winning layer per key (env / file /
default) without reading the value into your process.