You can define numeric validations with max and min values for int and floatCLI parameters:
importtyperfromtyping_extensionsimportAnnotateddefmain(id:Annotated[int,typer.Argument(min=0,max=1000)],age:Annotated[int,typer.Option(min=18)]=20,score:Annotated[float,typer.Option(max=100)]=0,):print(f"ID is {id}")print(f"--age is {age}")print(f"--score is {score}")if__name__=="__main__":typer.run(main)
Tip
Prefer to use the Annotated version if possible.
importtyperdefmain(id:int=typer.Argument(...,min=0,max=1000),age:int=typer.Option(20,min=18),score:float=typer.Option(0,max=100),):print(f"ID is {id}")print(f"--age is {age}")print(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 [required]
Options: --age INTEGER RANGE [default: 20] --score FLOAT RANGE [default: 0] --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 range 0<=x<=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 not in the range x>=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 not in the range x<=100.
π¬ But as we didn't specify a minimum score, this is acceptedpython main.py 5 --age 20 --score -5 ID is 5 --age is 20 --score is -5.0
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:
importtyperfromtyping_extensionsimportAnnotateddefmain(id:Annotated[int,typer.Argument(min=0,max=1000)],rank:Annotated[int,typer.Option(max=10,clamp=True)]=0,score:Annotated[float,typer.Option(min=0,max=100,clamp=True)]=0,):print(f"ID is {id}")print(f"--rank is {rank}")print(f"--score is {score}")if__name__=="__main__":typer.run(main)
Tip
Prefer to use the Annotated version if possible.
importtyperdefmain(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),):print(f"ID is {id}")print(f"--rank is {rank}")print(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 βπ¬ ID doesn't have clamp, so it shows an errorpython main.py 1002 Usage: main.py [OPTIONS] ID Try "main.py --help" for help.
Error: Invalid value for 'ID': 1002 is not in the range 0<=x<=1000.
π¬ But --rank and --score use clamppython main.py 5 --rank 11 --score -5 ID is 5 --rank is 10 --score is 0
You can make a CLI option work as a counter with the counter parameter:
importtyperfromtyping_extensionsimportAnnotateddefmain(verbose:Annotated[int,typer.Option("--verbose","-v",count=True)]=0):print(f"Verbose level is {verbose}")if__name__=="__main__":typer.run(main)
Tip
Prefer to use the Annotated version if possible.
importtyperdefmain(verbose:int=typer.Option(0,"--verbose","-v",count=True)):print(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 βπ¬ Check itpython main.py Verbose level is 0
π¬ Now use one --verbosepython main.py --verbose Verbose level is 1
π¬ Now 3 --verbosepython main.py --verbose --verbose --verbose Verbose level is 3
π¬ And with the short namepython main.py -v Verbose level is 1
π¬ And with the short name 3 timespython main.py -v -v -v Verbose level is 3
π¬ As short names can be put together, this also workspython main.py -vvv Verbose level is 3