From f2a8a254d971d064f66d7c02bed9bf4c22b64c24 Mon Sep 17 00:00:00 2001 From: Matthew Anderson Date: Mon, 17 Jul 2023 15:50:27 -0500 Subject: [PATCH] docs: use Annotated type (#41) --- docs/examples/decorator.md | 19 ++++++++++++------- docs/examples/pydantic.md | 17 ++++++++++------- docs/examples/pyproject.md | 17 ++++++++++------- docs/examples/schema.md | 17 ++++++++++------- docs/examples/simple_yaml.md | 18 +++++++++++------- docs/how.md | 6 +++++- 6 files changed, 58 insertions(+), 36 deletions(-) diff --git a/docs/examples/decorator.md b/docs/examples/decorator.md index d0e4c3c..5b170f6 100644 --- a/docs/examples/decorator.md +++ b/docs/examples/decorator.md @@ -9,6 +9,8 @@ This is meant to reduce boiler-plate code (compare to the [verbose example](/exa An example typer app: ```{.python title="simple_app.py" test="true"} +from typing_extensions import Annotated + import typer from typer_config import use_yaml_config @@ -16,11 +18,11 @@ app = typer.Typer() @app.command() -@use_yaml_config() # MUST BE AFTER @app.command() (1) +@use_yaml_config() # MUST BE AFTER @app.command() (1) def main( arg1: str, - opt1: str = typer.Option(...), - opt2: str = typer.Option("hello"), + opt1: Annotated[str, typer.Option()], + opt2: Annotated[str, typer.Option()] = "hello", ): typer.echo(f"{opt1} {opt2} {arg1}") @@ -99,19 +101,22 @@ This example shows you how save the parameters of the invoked command to a confi An example typer app: ```{.python title="simple_app.py" test="true"} +from typing_extensions import Annotated + import typer from typer_config.decorators import dump_json_config, use_json_config app = typer.Typer() + @app.command() -@use_json_config() # before dump decorator (1) -@dump_json_config("./dumped.json") +@use_json_config() # before dump decorator (1) +@dump_json_config("./dumped.json") def main( arg1: str, - opt1: str = typer.Option(...), - opt2: str = typer.Option("hello"), + opt1: Annotated[str, typer.Option()], + opt2: Annotated[str, typer.Option()] = "hello", ): typer.echo(f"{opt1} {opt2} {arg1}") diff --git a/docs/examples/pydantic.md b/docs/examples/pydantic.md index 61b0f7a..4189cda 100644 --- a/docs/examples/pydantic.md +++ b/docs/examples/pydantic.md @@ -7,6 +7,7 @@ This simple example uses a `--config` option to load a configuration from a YAML An example typer app: ```python title="simple_app.py" from typing import Any, Dict +from typing_extensions import Annotated from pydantic import BaseModel import typer @@ -33,13 +34,15 @@ app = typer.Typer() @app.command() def main( arg1: str, - config: str = typer.Option( - "", - callback=validator_callback, - is_eager=True, # THIS IS REALLY IMPORTANT (1) - ), - opt1: str = typer.Option(...), - opt2: str = typer.Option("hello"), + opt1: Annotated[str, typer.Option()], + opt2: Annotated[str, typer.Option()] = "hello", + config: Annotated[ + str, + typer.Option( + callback=validator_callback, + is_eager=True, # THIS IS REALLY IMPORTANT (1) + ), + ] = "", ): typer.echo(f"{opt1} {opt2} {arg1}") diff --git a/docs/examples/pyproject.md b/docs/examples/pyproject.md index 56c32d3..0579ad4 100644 --- a/docs/examples/pyproject.md +++ b/docs/examples/pyproject.md @@ -26,6 +26,7 @@ Then, we can read the values in our typer CLI: ```python title="my_tool.py" from typing import Any, Dict +from typing_extensions import Annotated import typer from typer_config import conf_callback_factory @@ -57,13 +58,15 @@ app = typer.Typer() @app.command() def main( arg1: str, - config: str = typer.Option( - "", - callback=pyproject_callback, - is_eager=True, # THIS IS REALLY IMPORTANT (1) - ), - opt1: str = typer.Option(...), - opt2: str = typer.Option("hello"), + opt1: Annotated[str, typer.Option()], + opt2: Annotated[str, typer.Option()] = "hello", + config: Annotated[ + str, + typer.Option( + callback=pyproject_callback, + is_eager=True, # THIS IS REALLY IMPORTANT (1) + ), + ] = "", ): typer.echo(f"{opt1} {opt2} {arg1}") diff --git a/docs/examples/schema.md b/docs/examples/schema.md index 54e8c63..87a6a19 100644 --- a/docs/examples/schema.md +++ b/docs/examples/schema.md @@ -7,6 +7,7 @@ This simple example uses a `--config` option to load a configuration from a YAML An example typer app: ```python title="simple_app.py" from typing import Any, Dict +from typing_extensions import Annotated from schema import Schema import typer @@ -30,13 +31,15 @@ app = typer.Typer() @app.command() def main( arg1: str, - config: str = typer.Option( - "", - callback=validator_callback, - is_eager=True, # THIS IS REALLY IMPORTANT (1) - ), - opt1: str = typer.Option(...), - opt2: str = typer.Option("hello"), + opt1: Annotated[str, typer.Option()], + opt2: Annotated[str, typer.Option()] = "hello", + config: Annotated[ + str, + typer.Option( + callback=validator_callback, + is_eager=True, # THIS IS REALLY IMPORTANT (1) + ), + ] = "", ): typer.echo(f"{opt1} {opt2} {arg1}") diff --git a/docs/examples/simple_yaml.md b/docs/examples/simple_yaml.md index d7146c8..8c9430b 100644 --- a/docs/examples/simple_yaml.md +++ b/docs/examples/simple_yaml.md @@ -6,6 +6,8 @@ This simple example uses a `--config` option to load a configuration from a YAML An example typer app: ```{.python title="simple_app.py" test="true"} +from typing_extensions import Annotated + import typer from typer_config import yaml_conf_callback @@ -15,13 +17,15 @@ app = typer.Typer() @app.command() def main( arg1: str, - config: str = typer.Option( - "", - callback=yaml_conf_callback, - is_eager=True, # THIS IS REALLY IMPORTANT (1) - ), - opt1: str = typer.Option(...), - opt2: str = typer.Option("hello"), + opt1: Annotated[str, typer.Option()], + opt2: Annotated[str, typer.Option()] = "hello", + config: Annotated[ + str, + typer.Option( + callback=yaml_conf_callback, + is_eager=True, # THIS IS REALLY IMPORTANT (1) + ), + ] = "", ): typer.echo(f"{opt1} {opt2} {arg1}") diff --git a/docs/how.md b/docs/how.md index a250d77..2993b36 100644 --- a/docs/how.md +++ b/docs/how.md @@ -8,5 +8,9 @@ The `typer` library then sees this extended signature and parses/generates the h Internally, the decorator then removes the `config` parameter from the arguments passed to the actual implementation that you wrote. Otherwise, your function would error with an unknown argument. -If you use the `config` parameter directly in your function, you _must_ use `is_eager=True` in the parameter definition because that will cause it to be processed first. +If you use the `config` parameter directly in your function, you **must** use `is_eager=True` in the parameter definition because that will cause it to be processed first. +For example: +```python +config: str = typer.Option("", is_eager=True, callback=...) +``` If you don't use `is_eager`, then your parameter values will depend on the order in which they were processed (read: unpredictably). \ No newline at end of file