Cookbook
Cookbook
Short, copy‑pasteable recipes. Each example is runnable; code is included from examples/.
Quickstart (load & resolve)
"""Quickstart: load YAML, resolve templates, and read values.
How to run locally:
PYTHONPATH=src uv run python examples/basic/01_quickstart.py
This example intentionally uses the shared config file under examples/config.
"""
from __future__ import annotations
import os
from pathlib import Path
from coyaml import YSettings
from coyaml.sources.yaml import YamlFileSource
def main() -> None:
# Set environment variables required by the example templates.
# Note: never do this in production code; prefer a real environment or .env.
os.environ['DB_USER'] = 'quick_user'
os.environ['DB_PASSWORD'] = 'quick_password' # noqa: S105
# Initialize settings and load YAML from the examples folder.
cfg = YSettings()
cfg_path = Path(__file__).resolve().parents[1] / 'config' / 'config.yaml'
cfg.add_source(YamlFileSource(cfg_path.as_posix()))
# Resolve all templates (env, file, config, yaml) after loading.
cfg.resolve_templates()
# Read values using attribute access (dot notation) and dotted keys.
print('index =', cfg.index)
print('llm =', cfg['llm'])
print('db_url =', cfg['debug.db.url'])
print('db_user =', cfg.debug.db.user)
if __name__ == '__main__':
main()
Dot access and setting values
"""Dot access vs dotted keys; setting values and nested creation.
Run:
PYTHONPATH=src uv run python examples/basic/02_dot_access_and_set.py
"""
from __future__ import annotations
from coyaml import YNode, YSettings
def main() -> None:
cfg = YSettings()
# Assign flat values via attributes and dotted keys.
cfg.index = 1
cfg['llm'] = 'gpt'
# Create nested structure with a dotted key; intermediate dicts are created automatically.
cfg['debug.db.url'] = 'sqlite:///example.db'
# Nested dictionaries are wrapped as YNode for convenient attribute access.
assert isinstance(cfg.debug, YNode) # noqa: S101
assert cfg.debug.db.url == 'sqlite:///example.db' # noqa: S101
print('index =', cfg.index)
print('llm =', cfg['llm'])
print('db_url =', cfg.debug.db.url)
if __name__ == '__main__':
main()
Convert to Pydantic model
"""Converting configuration (or subtrees) to Pydantic models using .to().
Run:
PYTHONPATH=src uv run python examples/basic/03_pydantic_to_method.py
"""
from __future__ import annotations
from pathlib import Path
from pydantic import BaseModel
from coyaml import YSettings
from coyaml.sources.yaml import YamlFileSource
class DatabaseConfig(BaseModel):
url: str
class DebugConfig(BaseModel):
db: DatabaseConfig
def main() -> None:
cfg = YSettings()
cfg_path = Path(__file__).resolve().parents[1] / 'config' / 'config.yaml'
cfg.add_source(YamlFileSource(cfg_path.as_posix()))
# Convert a subtree to a Pydantic model
debug: DebugConfig = cfg.debug.to(DebugConfig)
print('debug.db.url =', debug.db.url)
# Convert the whole tree to a Pydantic model
full: DebugConfig = cfg.to(DebugConfig)
# Note: this will fail unless the top-level shape matches DebugConfig.
# It is here to demonstrate that .to() can be called at any level.
_ = full
if __name__ == '__main__':
main()
Templates: env/file/config/yaml
"""Templates showcase: env, file, config, yaml.
Run:
PYTHONPATH=src uv run python examples/templates/10_env_file_config_yaml.py
This uses shared YAML under examples/config/config.yaml which contains all template types.
"""
from __future__ import annotations
import os
from pathlib import Path
from coyaml import YSettings
from coyaml.sources.yaml import YamlFileSource
def main() -> None:
# Prepare environment for env templates
os.environ['DB_USER'] = 'templ_user'
os.environ['DB_PASSWORD'] = 'templ_password' # noqa: S105
cfg = YSettings()
cfg_path = Path(__file__).resolve().parents[1] / 'config' / 'config.yaml'
cfg.add_source(YamlFileSource(cfg_path.as_posix()))
cfg.resolve_templates()
# env
print('env user:', cfg['debug.db.user'])
# file (reads tests/config/init.sql)
print('file snippet length:', len(cfg['debug.db.init_script']))
# config (builds db_url from other values)
print('config db_url:', cfg['app.db_url'])
# yaml (loads and merges external yaml)
print('yaml feature:', cfg['app.extra_settings.feature_flags.enable_new_feature'])
if __name__ == '__main__':
main()
Injection: explicit path
"""Injection by explicit dotted path using Annotated + YResource.
Run:
PYTHONPATH=src uv run python examples/injection/20_inject_by_explicit_path.py
"""
from __future__ import annotations
from typing import Annotated
from coyaml import YRegistry, YResource, YSettings, coyaml
from coyaml.sources.yaml import YamlFileSource
def setup() -> None:
cfg = YSettings()
cfg.add_source(YamlFileSource('tests/config/config.yaml'))
cfg.resolve_templates()
YRegistry.set_config(cfg)
@coyaml
def handler(user: Annotated[str, YResource('debug.db.user')]) -> str:
return user
def main() -> None:
setup()
print('user =', handler())
if __name__ == '__main__':
main()
Injection: by name with mask
"""Injection by parameter name constrained by mask.
Run:
PYTHONPATH=src uv run python examples/injection/22_inject_by_name_with_mask.py
"""
from __future__ import annotations
from typing import Annotated
from coyaml import YRegistry, YResource, YSettings, coyaml
def setup() -> None:
cfg = YSettings({'debug': {'db': {'user': 'dev_user'}}, 'prod': {'db': {'user': 'prod_user'}}})
YRegistry.set_config(cfg)
@coyaml(mask='debug.**')
def handler(user: Annotated[str | None, YResource()] = None) -> str | None:
return user
def main() -> None:
setup()
print('user =', handler())
if __name__ == '__main__':
main()