Use Pydantic models as Click options
Project description
pydanclick
Use Pydantic models as Click options.
Getting started
Install:
pip install pydanclick
Let's assume you have a Pydantic model:
class TrainingConfig(BaseModel):
epochs: int
lr: Annotated[float, Field(gt=0)] = 1e-4
early_stopping: bool = False
Add all its fields as options in your Click command:
from pydanclick import from_pydantic
@click.command()
@from_pydantic("config", TrainingConfig)
def cli(config: TrainingConfig):
"""A simple example with a few parameters and default behavior."""
# Here, we receive an already validated Pydantic object.
click.echo(config.model_dump_json(indent=2))
~ python my_app.py --help
Usage: my_app.py [OPTIONS]
A simple example with a few parameters and default behvior.
Options:
--early-stopping / --no-early-stopping
--lr FLOAT RANGE [x>0]
--epochs INTEGER [required]
--help Show this message and exit.
- Find examples in the
examples/folder - See the API Reference for the full list of options
Features
Use native Click types
The following types are converted to native Click types:
| Pydantic type | Converted to |
|---|---|
bool |
click.BOOL |
str |
click.STRING |
int |
click.INT |
float |
click.FLOAT |
conint, Annotated[int, Field(lt=..., ge=...) |
click.IntRange() |
confloat, Annotated[float, Field(lt=..., ge=...) |
click.FloatRange() |
pathlib.Path |
click.Path() |
uuid.UUID |
click.UUID |
datetime.datetime, datetime.date |
click.DateTime() |
Literal |
click.Choice |
More complex validators will be handled through Pydantic usual validation logic: once handled by Click, all arguments will be used to initialize Pydantic model.
Add multiple models
pydanclick.from_pydantic can be called several times with different models.
Use the prefix parameter to namespace the options from different models:
class Foo(BaseModel):
a: str = ""
b: str = ""
class Bar(BaseModel):
x: int = 0
y: int = 0
@click.command()
@from_pydantic("foo", Foo, prefix="foo")
@from_pydantic("bar", Bar, prefix="bar")
def cli(foo: Foo, bar: Bar):
pass
will give
~ python cli.py
Usage: cli.py [OPTIONS]
Options:
--foo-a TEXT
--foo-b TEXT
--bar-x INTEGER
--bar-y INTEGER
--help Show this message and exit.
Add regular options and arguments
pydanclick can be used alongside regular options and arguments:
@click.command()
@click.argument("arg")
@click.option("--option")
@from_pydantic("foo", Foo)
def cli(arg, option, foo: Foo):
pass
will give:
~ python cli.py
Usage: cli.py [OPTIONS] ARG
Options:
--option TEXT
--a TEXT
--b TEXT
--help Show this message and exit.
Option documentation
Options added with pydanclick.from_pydantic will appear in the command help page.
Model docstring is used to document options automatically (requires griffe, e.g. pip install pydanclick[griffe]). Enabled by default, use parse_docstring=False to disable. Use docstring_tyle to choose between google, numpy and sphinx coding style.
pydanclick also supports the Field(description=...) syntax from Pydantic.
To specify custom documentation for a given field, use extra_options={"my_field": "my help string"}.
Provided griffe is installed, using:
class Baz(BaseModel):
"""Some demo model.
Attributes:
a: this comes from the docstring
"""
a: int = 0
b: Annotated[int, Field(description="this comes from the field description")] = 0
c: int = 0
@click.command()
@from_pydantic("baz", Baz, extra_options={"c": {"help": "this comes from the `extra_options`"}})
def cli(baz: Baz):
pass
will give:
~ python cli.py --help
Usage: cli.py [OPTIONS]
Options:
--a INTEGER this comes from the docstring
--b INTEGER this comes from the field description
--c INTEGER this comes from the `extra_options`
--help Show this message and exit.
Customize option names
Specify option names with prefix and short option names with shorten:
@click.command()
@from_pydantic("foo", Foo, rename={"a": "--alpha", "b": "--beta"}, shorten={"a": "-A", "b": "-B"})
def cli(foo: Foo):
pass
will give:
~ python cli.py --help
Usage: cli.py [OPTIONS]
Options:
-A, --alpha TEXT
-B, --beta TEXT
--help Show this message and exit.
Pass extra parameters
Use extra_options to pass extra parameters to click.option for a given field.
API Reference
Functions:
- from_pydantic – Decorator to add fields from a Pydantic model as options to a Click command.
pydanclick.from_pydantic
from_pydantic(__var, model, *, exclude=(), rename=None, shorten=None, prefix='', parse_docstring=True, docstring_style='google', extra_options=None)
Decorator to add fields from a Pydantic model as options to a Click command.
Example:
@click.command()
@pydanclick.from_pydantic("arg_name", SomePydanticModel)
def my_command(arg_name: SomePydanticModel):
assert isinstance(arg_name, SomePydanticModel) # True
Parameters:
- __var (
str) – name of the variable that will receive the Pydantic model in the decorated function - model (
type[BaseModel]) – Pydantic model - exclude (
Sequence[str]) – field names that won't be added to the command - rename (
dict[str, str] | None) – a mapping from field names to command line option names (this will override any prefix). Option names must start with two dashes - shorten (
dict[str, str] | None) – a mapping from field names to short command line option names. Option names must start with one dash - prefix (
str) – a prefix to add to option names (without any dash) - parse_docstring (
bool) – if True andgriffeis installed, parse the docstring of the Pydantic model and pass argument documentation to the Clickhelpoption - docstring_style (
str) – style of the docstring (google,numpyorsphinx). Ignored ifparse_docstringis False - extra_options (
dict[str, _ParameterKwargs] | None) – a mapping from field names to a dictionary of options passed to theclick.option()function
Returns:
Contributing
Install the environment and the pre-commit hooks with
make install
Run tests with:
pytest
Limitations
pydanclick doesn't support (yet!):
- Nested models
- Container types (tuples, lists, dicts) or other complex types
- Converting fields to arguments, instead of options
- Some union types won't work
- Python
<3.11
Other missing features:
- Reading model from file
- Specifying all field-specific options directly in the Pydantic model (would allow easier re-use)
- Most Click features should be supported out-of-the-box through the
extra_optionsparameter. However, most of them aren't tested - Click and Pydantic both include validation logic. In particular, Click support custom
ParamType, validation callbacks andBadParametererrors: it's not clear if we want to fully rely on Pydantic or on Click or on a mixture of both
Repository initiated with fpgmaas/cookiecutter-poetry.
Project details
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
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pydanclick-0.1.0.tar.gz.
File metadata
- Download URL: pydanclick-0.1.0.tar.gz
- Upload date:
- Size: 8.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.7.1 CPython/3.11.8 Linux/6.2.0-1019-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3210c48164f99e9236f9021185f8c5a835677f1bbe37110014ee311fd29e1e36
|
|
| MD5 |
a4c6099390823fe7353a1a05963707ce
|
|
| BLAKE2b-256 |
c339b752fe5cd83277af36c7b175471788579f359a42eda53c6e04bb21d538bd
|
File details
Details for the file pydanclick-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pydanclick-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.7.1 CPython/3.11.8 Linux/6.2.0-1019-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb24fed618643c473d599b00e0d8f5242dddcf8e2d83466d44da1c29ee8d9c4d
|
|
| MD5 |
055eb24692da4b9b308427a2479c8e4c
|
|
| BLAKE2b-256 |
2396f749af6efa86228d604057d0add2d43723927e5242ea95784ccaae3d0a3c
|