📝 Add docs and examples for CLI parameters with multiple values
This commit is contained in:
parent
ff37cb874f
commit
fb8622b8bb
8 changed files with 247 additions and 0 deletions
|
@ -0,0 +1,15 @@
|
|||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
import typer
|
||||
|
||||
|
||||
def main(files: List[Path], celebration: str):
|
||||
for path in files:
|
||||
if path.is_file():
|
||||
typer.echo(f"This file exists: {path.name}")
|
||||
typer.echo(celebration)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
typer.run(main)
|
15
docs/src/multiple_values/multiple_options/tutorial001.py
Normal file
15
docs/src/multiple_values/multiple_options/tutorial001.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
from typing import List
|
||||
|
||||
import typer
|
||||
|
||||
|
||||
def main(user: List[str] = typer.Option(None)):
|
||||
if not user:
|
||||
typer.echo("No provided users")
|
||||
raise typer.Abort()
|
||||
for u in user:
|
||||
typer.echo(f"Processing user: {u}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
typer.run(main)
|
11
docs/src/multiple_values/multiple_options/tutorial002.py
Normal file
11
docs/src/multiple_values/multiple_options/tutorial002.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
from typing import List
|
||||
|
||||
import typer
|
||||
|
||||
|
||||
def main(number: List[float] = typer.Option([])):
|
||||
typer.echo(f"The sum is {sum(number)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
typer.run(main)
|
|
@ -0,0 +1,17 @@
|
|||
from typing import Tuple
|
||||
|
||||
import typer
|
||||
|
||||
|
||||
def main(user: Tuple[str, int, bool] = typer.Option((None, None, None))):
|
||||
username, coins, is_wizard = user
|
||||
if not username:
|
||||
typer.echo("No user provided")
|
||||
raise typer.Abort()
|
||||
typer.echo(f"The username {username} has {coins} coins")
|
||||
if is_wizard:
|
||||
typer.echo("And this user is a wizard!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
typer.run(main)
|
|
@ -0,0 +1,28 @@
|
|||
*CLI arguments* can also receive multiple values.
|
||||
|
||||
You can define the type of a *CLI argument* using `typing.List`.
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!./src/multiple_values/arguments_with_multiple_values/tutorial001.py!}
|
||||
```
|
||||
|
||||
And then you can pass it as many *CLI arguments* of that type as you want:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python main.py ./index.md ./first-steps.md woohoo!
|
||||
|
||||
This file exists: index.md
|
||||
woohoo!
|
||||
This file exists: first-steps.md
|
||||
woohoo!
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip
|
||||
We also declared a final *CLI argument* `celebration`, and it's correctly used even if we pass an arbitrary number of `files` first.
|
||||
|
||||
!!! info
|
||||
A `List` can only be used in the last command (if there are subcommands), as this will take anything to the right and assume it's part of the expected *CLI arguments*.
|
3
docs/tutorial/multiple-values/index.md
Normal file
3
docs/tutorial/multiple-values/index.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
There are several ways to declare multiple values for *CLI options* and *CLI arguments*.
|
||||
|
||||
We'll see them in the next short sections.
|
66
docs/tutorial/multiple-values/multiple-options.md
Normal file
66
docs/tutorial/multiple-values/multiple-options.md
Normal file
|
@ -0,0 +1,66 @@
|
|||
You can declare a *CLI option* that can be used multiple times, and then get all the values.
|
||||
|
||||
For example, let's say you want to accept several users in a single execution.
|
||||
|
||||
For this, use the standard Python `typing.List` to declare it as a `list` of `str`:
|
||||
|
||||
```Python hl_lines="1 6"
|
||||
{!./src/multiple_values/multiple_options/tutorial001.py!}
|
||||
```
|
||||
|
||||
You will receive the values as you declared them, as a `list` of `str`.
|
||||
|
||||
Check it:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python main.py
|
||||
|
||||
No provided users
|
||||
Aborted!
|
||||
|
||||
// Now pass a user
|
||||
$ python main.py --user Camila
|
||||
|
||||
Processing user: Camila
|
||||
|
||||
// And now try with several users
|
||||
$ python main.py --user Camila --user Rick --user Morty
|
||||
|
||||
Processing user: Camila
|
||||
Processing user: Rick
|
||||
Processing user: Morty
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Multiple `float`
|
||||
|
||||
The same way, you can use other types and they will be converted by **Typer** to their declared type:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!./src/multiple_values/multiple_options/tutorial002.py!}
|
||||
```
|
||||
|
||||
Check it:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python main.py
|
||||
|
||||
The sum is 0
|
||||
|
||||
// Try with some numbers
|
||||
$ python main.py --number 2
|
||||
|
||||
The sum is 2.0
|
||||
|
||||
// Try with some numbers
|
||||
$ python main.py --number 2 --number 3 --number 4.5
|
||||
|
||||
The sum is 9.5
|
||||
```
|
||||
|
||||
</div>
|
|
@ -0,0 +1,92 @@
|
|||
You can also declare a *CLI option* that takes several values of different types.
|
||||
|
||||
You can set the number of values and types to anything you want, but it has to be a fixed number of values.
|
||||
|
||||
For this, use the standard Python `typing.Tuple`:
|
||||
|
||||
```Python hl_lines="1 6"
|
||||
{!./src/multiple_values/options_with_multiple_values/tutorial001.py!}
|
||||
```
|
||||
|
||||
Each of the internal types defines the type of each value in the tuple.
|
||||
|
||||
So:
|
||||
|
||||
```Python
|
||||
user: Tuple[str, int, bool]
|
||||
```
|
||||
|
||||
means that the parameter `user` is a tuple of 3 values.
|
||||
|
||||
* The first value is a `str`.
|
||||
* The second value is an `int`.
|
||||
* The third value is a `bool`.
|
||||
|
||||
Later we do:
|
||||
|
||||
```Python
|
||||
username, coins, is_wizard = user
|
||||
```
|
||||
|
||||
If you hadn't seen that, it means that `user` is a tuple with 3 values, and we are assigning each of the values to a new variable:
|
||||
|
||||
* The first value in the tuple `user` (a `str`) goes to the variable `username`.
|
||||
* The second value in the tuple `user` (an `int`) goes to the variable `coins`.
|
||||
* The third value in the tuple `user` (a `bool`) goes to the variable `is_wizard`.
|
||||
|
||||
So, this:
|
||||
|
||||
```Python
|
||||
username, coins, is_wizard = user
|
||||
```
|
||||
|
||||
is equivalent to this:
|
||||
|
||||
```Python
|
||||
username = user[0]
|
||||
coins = user[1]
|
||||
is_wizard = user[2]
|
||||
```
|
||||
|
||||
!!! tip
|
||||
Notice that the default is a tuple with `(None, None, None)`.
|
||||
|
||||
You cannot simply use `None` here as the default because <a href="https://github.com/pallets/click/issues/472" target="_blank">Click doesn't support it</a>.
|
||||
|
||||
## Check it
|
||||
|
||||
Now let's see how this works in the terminal:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// check the help
|
||||
$ python main.py --help
|
||||
|
||||
// Notice the <TEXT INTEGER BOOLEAN>
|
||||
Usage: main.py [OPTIONS]
|
||||
|
||||
Options:
|
||||
--user <TEXT INTEGER BOOLEAN>...
|
||||
--install-completion Install completion for the current shell.
|
||||
--show-completion Show completion for the current shell, to copy it or customize the installation.
|
||||
--help Show this message and exit.
|
||||
|
||||
// Now try it
|
||||
$ python main.py --user Camila 50 yes
|
||||
|
||||
The username Camila has 50 coins
|
||||
And this user is a wizard!
|
||||
|
||||
// With other values
|
||||
$ python main.py --user Morty 3 no
|
||||
|
||||
The username Morty has 3 coins
|
||||
|
||||
// Try with invalid values (not enough)
|
||||
$ python main.py --user Camila 50
|
||||
|
||||
Error: --user option requires 3 arguments
|
||||
```
|
||||
|
||||
</div>
|
Loading…
Reference in a new issue