Presenter: Dominic Kempf, Scientific Software Center
Click is a Python package for creating beautiful command line interfaces in a composable way with as little code as necessary.
Natural evolution of a piece of research software in Python:
For the last step, good Command Line Interface (CLI) is very helpful. Important aspects:
We get access to command line arguments similar to C through sys.argv
:
# DON'T DO THIS!
import sys
inputfile = sys.argv[1]
print(f"Calculating statistics from {inputfile}")
Why is this bad?
The standard libraries argparse
and optparse
are better options, but there is even better.
import click
@click.command()
@click.argument("inputfile", type=click.Path(exists=True))
def stats(inputfile):
"""Read data from the given INPUTFILE and calculate useful statistics"""
click.echo(f"Calculating statistics from {inputfile}")
# This allows use of this Python file both for imports and for the CLI
if __name__ == "__main__":
stats()
Arguments are positional and only too a small extent optional or defaultable. Use them only for absolute essential, self-explanatory input. To customize your script's behavious options are the better choice:
import click
@click.command()
@click.option(
"--input",
type=click.Path(exists=True),
default="input.txt",
help="The data file to read from",
)
@click.option(
"--verbose/--no-verbose", type=bool, help="Whether to output intermediate results"
)
def stats(verbose, input):
"""Read data and calculate useful statistics"""
if verbose:
click.echo("Started the CLI script")
click.echo(f"Calculating statistics from {input}")
if __name__ == "__main__":
stats()
Add subcommand structure by reusing previously defined commands:
@click.group()
def main():
pass
@click.command()
def preprocess():
click.echo("Apply preprocessing")
main.add_command(stats)
main.add_command(preprocess)
if __name__ == "__main__":
main()
This mechanism is very powerful: arbitrary nesting, runtime extension e.g. through plugins etc.
As software becomes more mature, it is also advisable to package and distribute it as a Python package. Click easily integrates with setuptools
as well using the entrypoints mechanism:
# In setup.py
setup(entry_points={"console_scripts": ["myscript = mypackage.mymodule:myclifunction"]})
# In setup.cfg
[options.entry_points]
console_scripts =
myscript = mypackage.mymodule:myclifunction
Today's presentation can be found on the Lunch Time Python website: https://ssciwr.github.io/lunch-time-python/
For further information, see also the (very good) Click documentation
For questions to the Scientific Software Center, please write us to ssc@iwr.uni-heidelberg.de
Library options, please vote now: