Fallback Config Example
This example demonstrates fallback configuration where the first existing config file from a list is used. This is useful when you want to check multiple locations for a config file and use the first one found.
This pattern is similar to how tools like Ansible look for ansible.cfg:
- Check current directory first
- Fall back to user's home directory
- Fall back to system-wide config
An example typer app:
simple_app.py
from typing_extensions import Annotated
import typer
from typer_config.decorators import use_fallback_config
app = typer.Typer()
@app.command()
@use_fallback_config(fallback_files=["local.yml", "default.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 a default config file (local.yml doesn't exist in this example):
default.yml
name: World
greeting: Hello
suffix: "!"
Since local.yml doesn't exist, default.yml is used:
Terminal
$ python simple_app.py
Hello, World!
$ python simple_app.py --greeting Hi
Hi, World!
Now if we create a local config, it takes priority:
local.yml
name: Team
greeting: Hey
suffix: "!!"
Terminal (with local.yml)
$ python simple_app.py
Hey, Team!!
The --config option always takes priority over the fallback list:
override.yml
name: Boss
greeting: Yo
suffix: "!!!"
Terminal (with --config)
$ python simple_app.py --config override.yml
Yo, Boss!!!
A real-world example with typical config locations:
@app.command()
@use_fallback_config(fallback_files=[
"./myapp.yml", # local project config (highest priority)
"~/.config/myapp/config.yml", # user config
"/etc/myapp/config.yml", # system config (lowest priority)
])
def main(...):
...