import click
import inspectIn this application I need to use command line options to create class objects. In order not to repeat all class arguments in the Click configuration, I created a simple function to dynamically create Click options. See the source notebook of this page on Github
We have 2 classes, we want to pass the class name as argument to the command line tool and then all its arguments, for example:
createclass aclass --a somestring --b 6
We also use Python typing so we can pass that to Click.
class AClass:
def __init__(
self,
a: str,
b: int):
passclass BClass:
def __init__(
self,
c: float,
d: bool,
under_score: str):
passdef options_from_class(cls):
def decorator(f):
for par in inspect.signature(cls.__init__).parameters.values():
if par.name not in ["self"]:
click.option("--" + par.name, required=True, type=par.annotation)(f)
return f
return decorator@click.group()
def cli():
pass@cli.command()
@options_from_class(AClass)
def aclass(**kwargs):
click.echo('kwargs: {}'.format(kwargs))
ac = AClass(**kwargs)@cli.command()
@options_from_class(BClass)
def bclass(**kwargs):
click.echo('kwargs: {}'.format(kwargs))
bc = BClass(**kwargs)if __name__ == '__main__':
cli()Convert the Notebook to a Python script with:
jupyter nbconvert click-commandline-class-arguments.ipynb --to python
Finally test at the command line:
$ python click-commandline-class-arguments.py aclass --help
Usage: click-commandline-class-arguments.py aclass [OPTIONS]
Options:
--b INTEGER [required]
--a TEXT [required]
--help Show this message and exit.
python click-commandline-class-arguments.py bclass --help
Usage: click-commandline-class-arguments.py bclass [OPTIONS]
Options:
--under_score TEXT [required]
--d BOOLEAN [required]
--c FLOAT [required]
--help Show this message and exit.
$ python click-commandline-class-arguments.py bclass --d true --c 4.5 --under_score works
kwargs: {'d': True, 'c': 4.5, 'under_score': 'works'}