Package: pydanclick
pydanclickUse Pydantic models as Click options.Getting startedInstall:pipinstallpydanclickLet's assume you have a Pydantic model:classTrainingConfig(BaseModel):epochs:intlr:Annotated[float,Field(gt=0)]=1e-4early_stopping:bool=FalseAdd all its fields as options in your Click command:frompydanclickimportfrom_pydantic@click.command()@from_pydantic("config",TrainingConfig)defcli(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))~pythonmy_app.py--help
Usage:my_app.py[OPTIONS]Asimpleexamplewithafewparametersanddefaultbehvior.

Options:--early-stopping/--no-early-stopping--lrFLOATRANGE[x>0]--epochsINTEGER[required]--helpShowthismessageandexit.Find examples in theexamples/folderSee theAPI Referencefor the full list of optionsFeaturesUse native Click typesThe following types are converted to native Click types:Pydantic typeConverted toboolclick.BOOLstrclick.STRINGintclick.INTfloatclick.FLOATconint,Annotated[int, Field(lt=..., ge=...)click.IntRange()confloat,Annotated[float, Field(lt=..., ge=...)click.FloatRange()pathlib.Pathclick.Path()uuid.UUIDclick.UUIDdatetime.datetime,datetime.dateclick.DateTime()Literalclick.ChoiceMore 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 modelspydanclick.from_pydanticcan be called several times with different models.Use theprefixparameter to namespace the options from different models:classFoo(BaseModel):a:str=""b:str=""classBar(BaseModel):x:int=0y:int=0@click.command()@from_pydantic("foo",Foo,prefix="foo")@from_pydantic("bar",Bar,prefix="bar")defcli(foo:Foo,bar:Bar):passwill 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 argumentspydanclickcan be used alongside regular options and arguments:@click.command()@click.argument("arg")@click.option("--option")@from_pydantic("foo",Foo)defcli(arg,option,foo:Foo):passwill give:~ python cli.py
Usage: cli.py [OPTIONS] ARG

Options:
  --option TEXT
  --a TEXT
  --b TEXT
  --help         Show this message and exit.Option documentationOptions added withpydanclick.from_pydanticwill appear in the command help page.Model docstring is used to document options automatically (requiresgriffe, e.g.pip install pydanclick[griffe]). Enabled by default, useparse_docstring=Falseto disable. Usedocstring_tyleto choose betweengoogle,numpyandsphinxcoding style.pydanclickalso supports theField(description=...)syntax from Pydantic.To specify custom documentation for a given field, useextra_options={"my_field": "my help string"}.Providedgriffeis installed, using:classBaz(BaseModel):"""Some demo model.Attributes:a: this comes from the docstring"""a:int=0b:Annotated[int,Field(description="this comes from the field description")]=0c:int=0@click.command()@from_pydantic("baz",Baz,extra_options={"c":{"help":"this comes from the `extra_options`"}})defcli(baz:Baz):passwill 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 namesSpecify option names withprefixand short option names withshorten:@click.command()@from_pydantic("foo",Foo,rename={"a":"--alpha","b":"--beta"},shorten={"a":"-A","b":"-B"})defcli(foo:Foo):passwill give:~ python cli.py --help
Usage: cli.py [OPTIONS]

Options:
  -A, --alpha TEXT
  -B, --beta TEXT
  --help            Show this message and exit.Pass extra parametersUseextra_optionsto pass extra parameters toclick.optionfor a given field.API ReferenceFunctions:from_pydantic– Decorator to add fields from a Pydantic model as options to a Click command.pydanclick.from_pydanticfrom_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)defmy_command(arg_name:SomePydanticModel):assertisinstance(arg_name,SomePydanticModel)# TrueParameters:__var(str) – name of the variable that will receive the Pydantic model in the decorated functionmodel(type[BaseModel]) – Pydantic modelexclude(Sequence[str]) – field names that won't be added to the commandrename(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 dashesshorten(dict[str,str] | None) – a mapping from field names to short command line option names. Option names must start with one dashprefix(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 Clickhelpoptiondocstring_style(str) – style of the docstring (google,numpyorsphinx). Ignored ifparse_docstringis Falseextra_options(dict[str,_ParameterKwargs] | None) – a mapping from field names to a dictionary of options passed to theclick.option()functionReturns:Callable[[Callable[..., T]],Callable[..., T]]– a decorator that adds options to a functionContributingInstall the environment and the pre-commit hooks withmakeinstallRun tests with:pytestLimitationspydanclickdoesn't support (yet!):Nested modelsContainer types (tuples, lists, dicts) or other complex typesConverting fields to arguments, instead of optionsSome union types won't workPython<3.11Other missing features:Reading model from fileSpecifying 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 theextra_optionsparameter. However, most of them aren't testedClick and Pydantic both include validation logic. In particular, Click support customParamType, validation callbacks andBadParametererrors: it's not clear if we want to fully rely on Pydantic or on Click or on a mixture of bothRepository initiated withfpgmaas/cookiecutter-poetry.