Running the following code as python script.py
does nothing. I expect at least the click.echo
statement to get printed. It seems like the call to first_command
doesn't work. Any idea why?
import click
def multiple_input_option(**option_kwargs):
def decorator(func):
def _callback(ctx, param, value):
ctx.obj['multiple_options'] = value
help_text = 'some options to get from user'
keyword_arguments = {
'help': help_text,
'callback': _callback,
'expose_value': False,
'multiple': True,
}
keyword_arguments.update(**option_kwargs)
return click.option('--multiple-options', '-e', **keyword_arguments)(func)
return decorator
@click.command()
@multiple_input_option()
def first_command(ctx):
click.echo('> hello...first_command')
command_param_data = ctx.obj.keys()
click.echo(json.dumps(command_param_data, indent=2))
@click.group()
def hello_world(ctx):
"""
Your plugin description here
"""
ctx.ensure_object(dict)
# This is how we add more sub-commands
hello_world.add_command(first_command)
I came up with the following solution.
import click
#(1) import json, other wise json.dump will not work
import json
def multiple_input_option(**option_kwargs):
def decorator(func):
def _callback(ctx, param, value):
ctx.obj['multiple_options'] = value
help_text = 'some options to get from user'
keyword_arguments = {
'help': help_text,
'callback': _callback,
'expose_value': False,
'multiple': True,
}
keyword_arguments.update(**option_kwargs)
return click.option('--multiple-options', '-e', **keyword_arguments)(func)
return decorator
@click.command()
@multiple_input_option()
#(2) pass context here
@click.pass_context
def first_command(ctx):
click.echo('> hello...first_command')
command_param_data = ctx.obj.keys()
click.echo(json.dumps(command_param_data, indent=2))
@click.group()
#(3) pass context here
@click.pass_context
def hello_world(ctx):
"""
Your plugin description here
"""
ctx.ensure_object(dict)
# This is how we add more sub-commands
hello_world.add_command(first_command)
#(4) make a call in the main function
if __name__ == '__main__':
hello_world()
I had to do the following to make it work:
(1) Import the json module, so you could use json.dump
import json
(2)/(3) Since hello_world and first_command expect the context, you have to pass it via
click.pass_context
According to the Click documentation here,
[w]henever a Click command is executed, a Context object is created which holds state for this particular invocation. It remembers parsed parameters, what command created it, which resources need to be cleaned up at the end of the function, and so forth. It can also optionally hold an application-defined object.
A Context is, as stated above, an object of the class "Context" (see the Click API here for more information). The parameter "ctx" you use in hello_world and first_command is such an object. In hello_world you call the function "ensure_object" which is a function of the class "Context". Since you are using the context object, you have to make sure, that it is passed to your command, which is done by
click.pass_context
(4) At the end I added a main function, to call the command
if __name__ == '__main__':
hello_world()
One last word to json.dump
. I assume, you are using python 2.x, in that case the call is alright. For python 3.x, the call should look like that:
click.echo(json.dumps(list(command_param_data), indent=2))