Generate Click command line options dynamically from class arguments

python
Published

October 26, 2022

In 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

import click
import inspect

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):
        pass
class BClass:
    def __init__(
        self,
        c: float,
        d: bool,
        under_score: str):
        pass
def 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'}