Get the parameters passed to the click.group () subcommand

If I have click.group()

with multiple subcommands, is there a way that I can get the command line arguments passed to those subcommands within the group itself?

I know that you can go from group down through context

and I know that I can use a function callback

to be executed before the command, but I didn't know if there is a better way to do this than use callback

.

Example:

@click.group()
def cli():
    pass

@cli.command()
@click.argument('task')
@click.argument('task_id')
def sync(task, task_id):
    click.echo('Synching: {}'.format(task))

      

In this example, is there a way to get task

or task_id

in a group method?

+3


source to share


1 answer


This can be done with a method click.Group.invoke()

like:

Custom class:

class MyGroup(click.Group):
    def invoke(self, ctx):
        ctx.obj = tuple(ctx.args)
        super(MyGroup, self).invoke(ctx)

      

Using a custom class:

Then, to use a custom group, pass it as an argument cls

to the decorator group

, for example:

@click.group(cls=MyGroup)
@click.pass_context
def cli(ctx):
    args = ctx.obj
    ....

      

How it works?



It works because it click

is a well-designed OO framework. The decorator @click.group()

usually instantiates the object click.Group

, but allows this behavior to exceed the parameter cls

. So it's relatively easy to inherit from click.Group

in our own class and overcome the desired methods.

In this case, we click.Group.invoke()

'll go through and take the arguments and put them in the box ctx.obj

. They are then available in the function cli()

.

Test code:

import click

class MyGroup(click.Group):
    def invoke(self, ctx):
        ctx.obj = tuple(ctx.args)
        super(MyGroup, self).invoke(ctx)

@click.group(cls=MyGroup)
@click.pass_context
def cli(ctx):
    args = ctx.obj
    click.echo('cli: {} {}'.format(ctx.invoked_subcommand, ' '.join(args)))

@cli.command()
@click.argument('task')
@click.argument('task_id')
def sync(task, task_id):
    click.echo('Synching: {}'.format(task))

cli('sync task taskid'.split())

      

Results:

cli: sync task taskid
Synching: task

      

+3


source







All Articles