Utilities for working with configuration files in typer CLIs.
Project description
typer-config
This is a collection of utilities to use configuration files to set parameters for a typer CLI. It is useful for typer commands with many options/arguments so you don't have to constantly rewrite long commands. This package was inspired by phha/click_config_file and prototyped in this issue. It allows you to set values for CLI parameters using a configuration file.
Installation
$ pip install typer-config[all]
Note: that will include libraries for reading from YAML and TOML files as well. Feel free to leave off the optional dependencies if you don't need YAML or TOML capabilities.
Example
Simple YAML
An example typer app:
# typer_config.py
import typer
import typer_config
app = typer.Typer( )
@app.command()
def main(
arg1: str,
config: str = typer.Option(
"",
callback=typer_config.yaml_conf_callback,
is_eager=True, # THIS IS REALLY IMPORTANT
),
opt1: str = typer.Option(...),
opt2: str = typer.Option("hello"),
):
typer.echo(f"{opt1} {opt2} {arg1}")
if __name__ == "__main__":
app()
With a config file:
# config.yaml
arg1: stuff
opt1: things
opt2: nothing
And invoked with python:
$ python typer_config.py --config config.yml
things nothing stuff
$ python typer_config.py --config config.yml others
things nothing others
$ python typer_config.py --config config.yml --opt1 people
people nothing stuff
Note: this package also provides
json_conf_callback
andtoml_conf_callback
for those file formats.
Custom file loader
If you use an unsupported file format or need to do extra processing of the file, you can make your own file loader and construct an appropriate callback.
Suppose you want to specify parameters in a section of pyproject.toml
:
[tool.my_tool.parameters]
arg1 = "stuff"
opt1 = "things"
opt2 = "nothing"
Then, we can read the values in our typer CLI:
# typer_config.py
import typer
import typer_config
from typing import Any, Dict
def pyproject_loader(path: str) -> Dict[str, Any]:
if not path: # set a default path to read from
path = "pyproject.toml"
pyproject = toml.load("pyproject.toml")
conf = pyproject["tool"]["my_tool"]
return conf
pyproject_callback = typer_config.conf_callback_factory(pyproject_loader)
app = typer.Typer( )
@app.command()
def main(
arg1: str,
config: str = typer.Option(
"",
callback=pyproject_callback,
is_eager=True, # THIS IS REALLY IMPORTANT
),
opt1: str = typer.Option(...),
opt2: str = typer.Option("hello"),
):
typer.echo(f"{opt1} {opt2} {arg1}")
if __name__ == "__main__":
app()
And we get this behavior:
$ ls .
my_tool.py other.toml pyproject.toml
$ python my_tool.py
things nothing stuff
$ python typer_config.py others
things nothing others
$ python my_tool.py --config other.toml
something else entirely
How it works
This works by mutating the default values in the underlying click context (click.Context.default_map
) before the command is executed.
It is essentially overwriting the default values that you specified in your source code.
Note: You must use
is_eager=True
in the parameter definition because that will cause it to be processed first. If you don't useis_eager
, then your parameter values will depend on the order in which they were processed (read: unpredictably).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for typer_config-0.1.2-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 475bdae9e7933a937d0b822e214a792399352f68860022357ba92393bca4cd4f |
|
MD5 | 712e691bb31a6b47418ae1ea4b8afe02 |
|
BLAKE2b-256 | 73f0381591a851983381e178b4dba2c872b377150978fb021e765ddcbc98e2fe |