Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Click: Multiple Key Value Pair Arguments

I'm using the Python Click library for my command-line interface. I'd like to have a command that takes multiple key value pairs. I'm flexible on the api. For example

my_cli my_command FOO=1 BAR=2

or maybe

my_cli my_command FOO 1 BAR 2

or even

my_cli my_command {"FOO": 1, "BAR": 2}

Is there an easy way to do this with Click?

like image 895
Jesse Shieh Avatar asked Jul 03 '18 23:07

Jesse Shieh


People also ask

Can a key value pair have multiple values?

Also, in a serialized pair, a special indicator is used to separate the values within the key-value set. Finally, standard and serialized key-values can contain single or multiple values.

What is on click option?

A user interface technique for Mac computers, where the Option key is depressed and held down while the mouse is clicked on an item onscreen. Depending on the context — what is clicked, which app is active, etc., — a variety of functions may be initiated.

What is Click option in Python?

Click, or “Command Line Interface Creation Kit” is a Python library for building command line interfaces. The three main points of Python Click are arbitrary nesting of commands, automatic help page generation, and supporting lazy loading of subcommands at runtime.

Which of the following is parameter of the click command?

Click supports two types of parameters for scripts: options and arguments. There is generally some confusion among authors of command line scripts of when to use which, so here is a quick overview of the differences. As its name indicates, an option is optional.


1 Answers

The simplest solution is basically the same thing you'd do with a regular Python function where you wanted an API like this.

Take a single parameter that groups the variable-length stream of arguments into a tuple. Then, what you do depends on whether you want separate arguments:

>>> def func(*args):
...     d = dict(zip(args[::2], args[1::2]))
...     print(d)
>>> func('FOO', 1, 'BAR', 2)
{'FOO': 1, 'BAR': 2}

… or combined key:value arguments:

>>> def func(*args):
...     d = dict(arg.split(':') for arg in args)
...     print(d)

This one is a bit hacky to use, because in Python, arguments aren't just space-separated words, but bear with me on that:

>>> func('FOO:1', 'BAR:2')
{'FOO': 1, 'BAR': 2}

The click equivalent for the first looks like this:

@click.command()
@click.argument('args', nargs=-1)
def my_command(args):
    d = dict(zip(args[::2], args[1::2]))
    click.echo(d)

(Obviously you can stick that in a click.group, etc., just like any other command.)

And now:

$ ./clicky.py FOO 1 BAR 2
{'FOO': 1, 'BAR': 2}

And the second looks like this:

@click.command()
@click.argument('args', nargs=-1)
def my_command(args):
    d = dict(arg.split(':') for arg in args)
    click.echo(d)

And notice that now, using it is not hacky at all, because to your shell, arguments are just words separated by spaces:

$ ./clicky.py FOO:1 BAR:2
{'FOO': 1, 'BAR': 2}

What if you want to handle both KEY=VALUE and KEY:VALUE? Then you just have to write something slightly more complicated than arg.split(':'). And you'll probably want some better error handling too. But that should be enough to get you started.

like image 91
abarnert Avatar answered Sep 17 '22 18:09

abarnert