Inheritance Config Example
This example demonstrates configuration inheritance where multiple config files are merged together, with later files overriding earlier ones. Nested dictionaries are deep-merged, preserving keys that aren't explicitly overridden.
This is useful for layered configuration like:
- System defaults (/etc/myapp.yaml)
- User overrides (~/.config/myapp.yaml)
- Project-local overrides (./myapp.yaml)
An example typer app:
simple_app.py
from typing_extensions import Annotated
import typer
from typer_config.decorators import use_multifile_config
app = typer.Typer()
@app.command()
@use_multifile_config(default_files=["base_config.yml", "local_config.yml"])
def main(
name: str,
greeting: Annotated[str, typer.Option()],
suffix: Annotated[str, typer.Option()] = "!",
):
typer.echo(f"{greeting}, {name}{suffix}")
if __name__ == "__main__":
app()
With config files representing different layers:
base_config.yml
name: World
greeting: Hello
suffix: "!"
local_config.yml
greeting: Hey
Note that local_config.yml only overrides greeting, while name and suffix
are inherited from base_config.yml.
And invoked with python:
Terminal
$ python simple_app.py
Hey, World!
$ python simple_app.py --suffix "!!"
Hey, World!!
$ python simple_app.py Alice
Hey, Alice!
Missing config files are silently skipped, so you can define optional override locations:
@app.command()
@use_multifile_config(default_files=[
"/etc/myapp/config.yml", # system defaults (may not exist)
"~/.config/myapp/config.yml", # user config (may not exist)
"./config.yml", # local config (may not exist)
])
def main(...):
...