If you don't insist on passing something that looks like a list, but simply want to pass multiple variadic arguments, you can use the multiple option.

From the click documentation

@click.command()
@click.option('--message', '-m', multiple=True)
def commit(message):
    click.echo('\n'.join(message))
$ commit -m foo -m bar
foo
bar
Answer from Jarno on Stack Overflow
Top answer
1 of 6
93

If you don't insist on passing something that looks like a list, but simply want to pass multiple variadic arguments, you can use the multiple option.

From the click documentation

@click.command()
@click.option('--message', '-m', multiple=True)
def commit(message):
    click.echo('\n'.join(message))
$ commit -m foo -m bar
foo
bar
2 of 6
41

You can coerce click into taking multiple list arguments, if the lists are formatted as a string literals of python lists by using a custom option class like:

Custom Class:

import click
import ast

class PythonLiteralOption(click.Option):

    def type_cast_value(self, ctx, value):
        try:
            return ast.literal_eval(value)
        except:
            raise click.BadParameter(value)

This class will use Python's Abstract Syntax Tree module to parse the parameter as a python literal.

Custom Class Usage:

To use the custom class, pass the cls parameter to @click.option() decorator like:

@click.option('--option1', cls=PythonLiteralOption, default=[])

How does this work?

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

In this case we over ride click.Option.type_cast_value() and then call ast.literal_eval() to parse the list.

Test Code:

@click.command(context_settings=dict(help_option_names=['-h', '--help']))
@click.option('--option1', cls=PythonLiteralOption, default=[])
@click.option('--option2', cls=PythonLiteralOption, default=[])
def cli(option1, option2):
    click.echo("Option 1, type: {}  value: {}".format(
        type(option1), option1))
    click.echo("Option 2, type: {}  value: {}".format(
        type(option2), option2))

# do stuff
if __name__ == '__main__':
    import shlex
    cli(shlex.split(
        '''--option1 '["o11", "o12", "o13"]' 
        --option2 '["o21", "o22", "o23"]' '''))

Test Results:

Option 1, type: <type 'list'>  value: ['o11', 'o12', 'o13']
Option 2, type: <type 'list'>  value: ['o21', 'o22', 'o23']
🌐
Click Documentation
click.palletsprojects.com › en › stable › options
Options — Click Documentation (8.5.x)
For both multiple and nargs with values other than 1, Click will invoke the ParamType.split_envvar_value() method to perform the splitting.
Discussions

click vs. argparse: Should the 'multiple' parameter be equivalent to 'nargs'?
For example, I have an option that takes up to three values, where the last two must be integers. import click @click.command() @click.option("--item", nargs=3, type=click.Tuple([str, int, int])) def putitem(item): name, i, j = item click.echo(f"name={name} id={i} count={j}") if __name__ == "__main__": putitem() "--item yourmom 10 1" name=yourmom id=10 count=1 "click.Tuple" and "name, i, j = item" should be self-explanatory. https://click.palletsprojects.com/en/8.1.x/options/#multi-value-options the only limitation is that "nargs" value must be known. click seems to like unambiguous commands. Error: Option '--item' requires 3 arguments. then again I can't make the third argument optional, can I? BUT, you can be tricksy. i'd suggest other libs that offers this functionality.. since fiddling with how the lib works will invariably lead to errors .. https://stackoverflow.com/a/44056564 More on reddit.com
🌐 r/learnpython
4
2
June 12, 2023
Option(prompt=True, multiple=True)
Click's support for 'prompt' is great! And many thanks for the excellent library :) However, prompt=True does not play well with multiple=True. Playing with this example: import click @... More on github.com
🌐 github.com
5
September 8, 2014
python - click.Choice for multiple arguments - Stack Overflow
As it turns out I misunderstood the usage of multiple=True when using @click.option. More on stackoverflow.com
🌐 stackoverflow.com
multiple input types ("either / or") for option in python click - Stack Overflow
Is it possible to specify two input types for a click.option, one of which the supplied value has to be in? In a normal python function with typing, I'd declare it like so: from typing import Union... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Readthedocs
pocoo-click.readthedocs.io › en › latest › options
Options - the Click Documentation
For instance, git commit -m foo -m bar would record two lines for the commit message: foo and bar. This can be accomplished with the multiple flag: ... @click.command() @click.option('--message', '-m', multiple=True) def commit(message): click.echo('\n'.join(message))
🌐
Click Documentation
click.palletsprojects.com › en › stable › parameters
Parameters — Click Documentation (8.5.x)
Click supports only two principle ... subcommands, urls, or files. Can take a fixed number of arguments. The default is 1. They may be specified multiple times using Multiple Options....
🌐
Reddit
reddit.com › r/learnpython › click vs. argparse: should the 'multiple' parameter be equivalent to 'nargs'?
r/learnpython on Reddit: click vs. argparse: Should the 'multiple' parameter be equivalent to 'nargs'?
June 12, 2023 -

I wrote a command line tool using Python's built-in argparse module, but then I heard good things about the Click package, so I thought I would give it a try and play around with it by rewriting my code.

The first difference I noticed is that Click has the multiple=True parameter to allow multiple arguments to be passed, but the way it works seems odd to me.

For example, I have an option that takes up to three values, where the last two must be integers. With argparse I just added nargs='+' and wrote a function for type conversion and error handling.

Example usage:

$ myprog --opt str_value 5 8

However, I can't seem to do this with Click. Here's how I would have to type the command using Click:

$ myprog --opt str_value --opt 5 --opt 8

Is Click really that limited or am I missing something? The documentation says that multiple is similar to nargs, but I don't really see it that way.

Also, what if I wanted to pass multiple files or paths in general? Something like mydir/**/*.txt works fine with argparse because it produces a list object.

Looking for similar functionality with Click, I only found that I could use type=(str, int, int), but then again I can't make the third argument optional, can I?

It would be great to hear some suggestions on how to correctly work with multiple arguments using Click.

Thanks in advance.

🌐
GitHub
github.com › pallets › click › issues › 218
Option(prompt=True, multiple=True) · Issue #218 · pallets/click
September 8, 2014 - However, prompt=True does not play well with multiple=True. Playing with this example: import click @click.command() @click.option('-v', '--value', prompt=True, multiple=True) def cli(value): print value # just print the value if __name__ == '__main__': # supporing env vars cli.main(auto_envvar_prefix='TEST') Let's first pass multiple options (it works): $ python cli.py -v1 -v2 -v3 (u'1', u'2', u'3') Great, now let's test the prompt: $ python cli.py Value [()]: 1 2 3 (u'1', u' ', u'2', u' ', u'3') Hmm, the input is not split using spaces!
Author: pallets
Find elsewhere
🌐
DevGenius
blog.devgenius.io › python-click-library-introduction-6ba5d936ef82
Python — Click Library Introduction | by Tony | Dev Genius
March 22, 2023 - You can define a multiple option in a Click command by using the click.option() decorator and passing the multiple=True parameter.
🌐
Real Python
realpython.com › python-click
Click and Python: Build Extensible and Composable CLI Apps – Real Python
March 18, 2026 - If you set it to True, then you can specify the underlying option multiple times. ... In this command, you specify the --name option two times. Each time, you use a different input value.
🌐
Click Documentation
click.palletsprojects.com › en › stable › options
Options — Click Documentation (8.2.x)
Click expects you to pass at least two positional arguments to the option decorator.
🌐
Readthedocs
pymbook.readthedocs.io › en › latest › click.html
Building command line applications with Click — Python for you and me 0.5.beta1 documentation
Building command line applications with Click · Installation, and development tips · Using echo for printing text · Boolean flags · Standard options in the command line · Same option multiple times · Help text for the script · Super fast way to accept password with confirmation ·
🌐
Readthedocs
pocoo-click.readthedocs.io › en › latest › advanced
Advanced Patterns - the Click Documentation
In this case, the callback will fire for exclude and it will be passed both options (foo and bar), then the callback for include will fire with baz only. Note that even if a parameter does not allow multiple versions, Click will still accept the position of the first, but it will ignore every value except the last.
🌐
GitHub
github.com › pallets › click › issues › 472
Tuples as Multi Value Options throw an TypeError · Issue #472 · pallets/click
November 30, 2015 - import click @click.command() @click.option('--item', type=(unicode, int)) def putitem(item): click.echo('name=%s id=%d' % item) putitem()
Author: pallets
🌐
UiPath Community
forum.uipath.com › help
Click the options from multiple option - Help - UiPath Community Forum
June 6, 2019 - what activity can i use in selecting one option in the multiple options? can any one help
🌐
GitHub
github.com › pallets › click › issues › 892
Choice option with "multiple=True" breaks with generator expressions · Issue #892 · pallets/click
December 1, 2017 - If you populate the choices of a click.option('--name', multiple=True, type=click.Choice()) with a generator expression and not with a list, the order in which click accepts the options becomes relevant.
Author: pallets
Top answer
1 of 2
2

You can use multiple with a tweak. Make the multiple=True. Accept the multiple values. And throw error if there are more than one item.

def check_multiple(ctx, param, value):
    if len(name) > 1:
        click.echo('Multiple options are not accepted!')
        ctx.abort()
@cli.command()
@click.option('--name', '-n', required=True, multiple=True, callback=check_multiple, help='Specify the name of the student')
def student(name):
    ''' '''

Since, I don't have a current setup, the above code is not tested; Derived from the documentation.

2 of 2
1

Use the kwargs

multiple=True

Running this

import click


@click.group()
@click.version_option("Development", help="Echo version and exit")
@click.help_option(help="Use this on subcommands for more information")
def cli():
    """Add a student/teacher/principal"""


def validate_student(ctx, param, value):
    try:
        if len(value) > 1:
            raise ValueError
        else:
            return value
    except ValueError:
        raise click.BadParameter('Students should be not more than 1')


@cli.command()
@click.option('--name', '-n', required=True, multiple=True, help='Specify the name of the student',
              callback=validate_student)
def student(name):
    """Add a Student"""
    print(name)


if __name__ == "__main__":
    student()

Gives me this

$ python3 add.py -n xx -n yy
    Usage: add.py [OPTIONS]

Error: Invalid value for "--name" / "-n": Students should be not more than 1

Process finished with exit code 0

But passing only 1 param returns:

$ python3 add.py -n xx
('xx',)

This is documented here: http://click.pocoo.org/5/options/#multi-value-options and here http://click.pocoo.org/5/options/#callbacks-for-validation

🌐
GitHub
github.com › pallets › click › issues › 190
how to set default for multi value options · Issue #190 · pallets/click
July 15, 2014 - import click @click.command() @click.option("-r", "--range", nargs=2, type=int, default=(1,2), show_default=True) def scale(range): print "scale to %d - %d" % range if __name__ == '__main__': scale() But the default value for the option of multi values doesn't work here.
Author: pallets
🌐
AssemblyAI
assemblyai.com › blog › the-definitive-guide-to-python-click
The Definitive Guide to Python Click
July 28, 2021 - Now let’s go through how to use the click.options decorator. This decorator is used when you want to pass optional parameters to your commands. It can be used to pass an argument, or to be passed as a flag.