Skip to content

Number

You can define numeric validations with max and min values for int and float CLI parameters:

import typer_cloup as typer


def main(
    id: int = typer.Argument(..., min=0, max=1000),
    age: int = typer.Option(20, min=18),
    score: float = typer.Option(0, max=100),
):
    typer.echo(f"ID is {id}")
    typer.echo(f"--age is {age}")
    typer.echo(f"--score is {score}")


if __name__ == "__main__":
    typer.run(main)

CLI arguments and CLI options can both use these validations.

You can specify min, max or both.

Check it:

fast β†’python main.py --help
πŸ’¬ Notice the extra RANGE in the help text for --age and --scoreUsage: main.py [OPTIONS] ID

Arguments:
ID [0<=x<=1000; required]

Options:
--age INTEGER RANGE [default: 20; x>=18]
--score FLOAT RANGE [default: 0; x<=100]
--help Show this message and exit.

πŸ’¬ Pass all the CLI parameterspython main.py 5 --age 20 --score 90
ID is 5
--age is 20
--score is 90.0

πŸ’¬ Pass an invalid IDpython main.py 1002
Usage: main.py [OPTIONS] ID
Try "main.py --help" for help.

Error: Invalid value for 'ID': 1002 is not in the valid range of 0 to 1000.

πŸ’¬ Pass an invalid agepython main.py 5 --age 15
Usage: main.py [OPTIONS] ID
Try "main.py --help" for help.

Error: Invalid value for '--age': 15 is smaller than the minimum valid value 18.

πŸ’¬ Pass an invalid scorepython main.py 5 --age 20 --score 100.5
Usage: main.py [OPTIONS] ID
Try "main.py --help" for help.

Error: Invalid value for '--score': 100.5 is bigger than the maximum valid value 100.

πŸ’¬ But as we didn't specify a minimum score, this is acceptedp

Clamping numbersΒΆ

You might want to, instead of showing an error, use the closest minimum or maximum valid values.

You can do it with the clamp parameter:

import typer_cloup as typer


def main(
    id: int = typer.Argument(..., min=0, max=1000),
    rank: int = typer.Option(0, max=10, clamp=True),
    score: float = typer.Option(0, min=0, max=100, clamp=True),
):
    typer.echo(f"ID is {id}")
    typer.echo(f"--rank is {rank}")
    typer.echo(f"--score is {score}")


if __name__ == "__main__":
    typer.run(main)

And then, when you pass data that is out of the valid range, it will be "clamped", the closest valid value will be used:

fast β†’python main.py 1002
Usage: main.py [OPTIONS] ID
Try "main.py --help" for help.

Error: Invalid value for 'ID': 1002 is not in the valid range of 0 to 1000.

python main.py 5 --rank 11 --score -5
ID is 5
--rank is 10
--score is 0

restart ↻

Counter CLI optionsΒΆ

You can make a CLI option work as a counter with the counter parameter:

import typer_cloup as typer


def main(verbose: int = typer.Option(0, "--verbose", "-v", count=True)):
    typer.echo(f"Verbose level is {verbose}")


if __name__ == "__main__":
    typer.run(main)

It means that the CLI option will be like a boolean flag, e.g. --verbose.

And the value you receive in the function will be the amount of times that --verbose was added:

fast β†’python main.py
Verbose level is 0

python main.py --verbose
Verbose level is 1

python main.py --verbose --verbose --verbose
Verbose level is 3

python main.py -v
Verbose level is 1

python main.py -v -v -v
Verbose level is 3

python main.py -vvv
Verbose level is 3

restart ↻
You can ask questions about Typer. Try:
How can I terminate a program?
How to launch applications?
How to add help to CLI argument?