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

后端 未结 1 804
攒了一身酷
攒了一身酷 2021-01-02 19:37

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 its

相关标签:
1条回答
  • 2021-01-02 20:28

    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
    
    0 讨论(0)
提交回复
热议问题