I'd like to create a CLI for my application that's flexible and extensible. Click seems like the right solution but I'm new to it and have not seen an example that fits what I'm looking for. The application has a variety of different inputs (file, TCP socket, ZMQ etc); a variety of different tasks it can perform (task1, task2, etc); and a variety of outputs (file, socket, etc). I'd like to have a CLI which allows the defining of these 3 stages.
Desired CLI example:
myapp.py \
source TCP --read-size=4096 127.0.0.1 8888 \
task taskABC --optional-arg example example 99 \
sink file myoutput.bin
The following code seems to provide most of what I want but only allows the specification of 1 of the 3 pipelines. Using the chain=True
option on the top level group yields the error RuntimeError: It is not possible to add multi commands as children to another multi command
and doesn't feel like the right answer as I want to require the specification of all 3 stages, not allow an arbitrary number of stage definitons.
Is my CLI vision achievable with Click?
import click
@click.group()
def cli():
pass
@cli.group()
def source():
pass
@source.command()
@click.argument("host")
@click.argument("port", type=click.INT)
def tcp(host, port):
"""Command for TCP based source"""
@source.command()
@click.argument("input_file", type=click.File('rb'))
def file(input_file):
"""Command for file based source"""
@cli.group()
def task():
pass
@task.command()
def example1():
"""Example 1"""
@task.command()
def example2():
"""Example 2"""
@cli.group()
def sink():
pass
@sink.command()
@click.argument("host", type=click.STRING)
@click.argument("port", type=click.INT)
def tcp(host, port):
"""Command for TCP based sink"""
@sink.command()
@click.argument("output_file", type=click.File('wb'))
def file(output_file):
"""Command for file based source"""
if __name__ == '__main__':
cli()```