Get params sent to a subcommand of a click.group()

半城伤御伤魂 提交于 2019-12-18 16:51:44

问题


If I have a click.group() with multiple sub-commands, is there a way that I can get the command line arguments passed to those sub-commands within the group itself?

I know you can go from the group downwards via the context, and I know that I can use a callback function that will execute before the command, but I didn't know if there was a better way to do this than use a callback.

An 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 any way to get task or task_id in the group method?


回答1:


This can be done by over riding the click.Group.invoke() method like:

Custom Class:

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

Using Custom Class:

Then to use the custom group, pass it as the cls argument to the group decorator like:

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

How does this work?

This works because click is a well designed OO framework. The @click.group() decorator usually instantiates a click.Group object but allows this behavior to be over ridden with the cls parameter. So it is a relatively easy matter to inherit from click.Group in our own class and over ride desired methods.

In this case we over ride click.Group.invoke() and grab the arguments and put them into the ctx.obj field. They are then accessible in the cli() function.

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


来源:https://stackoverflow.com/questions/44051647/get-params-sent-to-a-subcommand-of-a-click-group

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!