3.2 KiB
3.2 KiB
name, description
| name | description |
|---|---|
| python-development-settings | Application configuration and settings management. Use when defining, loading, validating, or extending application settings. |
Rules
- The root settings class must inherit from
pydantic_settings.BaseSettings. This enables automatic loading from environment variables and.envfiles. - Every nested settings class (for individual services, adapters, or components) must inherit from
pydantic.BaseModel, not fromBaseSettings. Only the root class needs the env-loading behavior. - The root settings class exposes one field per top-level service or subsystem. Provide sensible defaults as plain values for immutable types (str, int, bool, None) and use
Field(default_factory=...)only when the default is a mutable object (dict, list, or model instance). Never use mutable literals as class-attribute defaults in Pydantic v2. Provide defaults so the application starts without a config file when reasonable. - A settings class can accept either a settings object or a string key referencing another entry in the same config. The resolver (or a
@model_validator) replaces string references with resolved instances after initial parsing. This is how services declare their dependencies declaratively. - Use
@model_validator(mode="after")on the root settings class to validate cross-references between subsystems, resolve string keys to actual instances, and enforce consistency across the configuration graph. - Support loading from YAML config files with custom tags. Register
!includefor file inclusion and!envfor environment variable interpolation inside YAML. The YAML loader builder must live as a@staticmethodinside the root settings class. Example:@staticmethod def get_yaml_loader(base_path: pathlib.Path) -> yaml.BaseLoader: loader = type("Loader", (yaml.SafeLoader,), {}) loader.add_constructor( "!include", yaml_include.Constructor(base_dir=str(base_path)), ) loader.add_constructor("!env", construct_env_tag) return loader - Support loading from JSON config files using standard
json.load. JSON does not support custom tags; use string interpolation or env var resolution handled byBaseSettingsafter load. - Provide a single
load()classmethod on the root settings class that reads the config file (YAML or JSON), then passes the parsed dict into theBaseSettingsconstructor along with optional_env_prefixand_env_file. Example:@classmethod def load(cls, config_file: pathlib.Path | None = None) -> Self: data = {} if config_file is not None: if config_file.suffix in (".yaml", ".yml"): data.update(yaml.load(config_file.read_text(), Loader=get_loader())) elif config_file.suffix == ".json": data.update(json.loads(config_file.read_text())) return cls(**data) - Keep each subsystem's settings in its own
settings.pymodule inside the subsystem package. Import and compose them into the root settings class. Do not inline subsystem schemas into the root file. - Use
pydantic.Field(default_factory=...)for mutable default values (dicts, lists, models). Never use mutable literals as class-attribute defaults in Pydantic v2.