Click Group Chained Subcommands
Build chained Click subcommands where multiple steps run in sequence, sharing a result context and enforcing invocation order.
Code
import click
@click.group(chain=True)
@click.option('--verbose', is_flag=True, help='enable verbose output')
@click.pass_context
def cli(ctx, verbose):
ctx.ensure_object(dict)
ctx.obj['verbose'] = verbose
ctx.obj['results'] = []
@cli.command('extract')
@click.argument('source', type=click.Path(exists=True))
@click.pass_obj
def extract(state, source):
click.echo(f'extracting {source}')
state['results'].append(('extract', source))
@cli.command('transform')
@click.option('--uppercase', is_flag=True)
@click.pass_obj
def transform(state, uppercase):
if not any(step == 'extract' for step, _ in state['results']):
raise click.UsageError('transform must run after extract')
value = 'transformed-data'
if uppercase:
value = value.upper()
state['results'].append(('transform', value))
click.echo(f'transform ok: {value}')
@cli.result_callback()
def process_pipeline(pipeline, state, **kwargs):
click.echo('pipeline finished:')
for step, value in state['results']:
click.echo(f' {step} -> {value}')
if __name__ == '__main__':
cli()Report a problem with this exampleOpens a pre-filled issue on GitHub.