Typer
typer.tiangolo.com βΊ tutorial βΊ arguments βΊ help
CLI Arguments with Help - Typer
import typer app = typer.Typer() @app.command() def main(name: str = typer.Argument(..., help="The name of the user to greet")): print(f"Hello {name}") if __name__ == "__main__": app() And it will be used in the automatic --help option: $ uv run python main.py --help // Check the section with ...
Typer
typer.tiangolo.com βΊ tutorial βΊ parameter-types
CLI Parameter Types - Typer
// Call it with CLI parameters $ uv run python main.py Camila --age 15 --height-meters 1.70 --female // All the data has the correct Python type name is Camila, of type: class 'str' --age is 15, of type: class 'int' --height-meters is 1.7, of type: class 'float' --female is True, of type: class ...
Typer
typer.tiangolo.com βΊ tutorial βΊ multiple-values βΊ arguments-with-multiple-values
CLI Arguments with Multiple Values - Typer
Python 3.10+ from pathlib import Path import typer app = typer.Typer() @app.command() def main(files: list[Path], celebration: str): for path in files: if path.is_file(): print(f"This file exists: {path.name}") print(celebration) if __name__ == "__main__": app() And then you can pass it as ...
Typer
typer.tiangolo.com βΊ tutorial βΊ commands βΊ arguments
Command CLI Arguments - Typer
The same way as with a CLI application with a single command, subcommands (or just "commands") can also have their own CLI arguments: Python 3.10+ import typer app = typer.Typer() @app.command() def create(username: str): print(f"Creating user: {username}") @app.command() def delete(username: str): print(f"Deleting user: {username}") if __name__ == "__main__": app() // Check the help for create $ uv run python main.py create --help Usage: main.py create [OPTIONS] {username} Arguments: username [required] Options: --help Show this message and exit.
Jacob Kaplan-Moss
jacobian.org βΊ til βΊ common-arguments-with-typer
Common Arguments With Typer - Jacob Kaplan-Moss
import typer from types import SimpleNamespace cli = typer.Typer() @cli.callback() def main( ctx: typer.Context, pinboard_token: str = typer.Option(None, envvar="PINBOARD_TOKEN"), ): if not pinboard_token: print( "Missing pinboard token; pass --pinboard-token or set env[PINBOARD_TOKEN]" ) raise typer.Exit(1) ctx.obj = SimpleNamespace(pinboard_token = pinboard_token) @cli.command() def all(ctx: typer.Context): # do something with ctx.obj.pinboard_token @cli.command() def new(ctx: typer.Context): # do something with ctx.obj.pinboard_token if __name__ == "__main__": cli()
Typer
typer.tiangolo.com βΊ tutorial βΊ arguments βΊ optional
Optional CLI Arguments - Typer
In fact, it's very common to have optional CLI arguments, it's way more common than having required CLI options. As an example of how it could be useful, let's see how the ls CLI program works. // If you just type $ ls // ls will "list" the files and directories in the current directory typer tests README.md LICENSE // But it also receives an optional CLI argument $ ls ./tests/ // And then ls will list the files and directories inside of that directory from the CLI argument __init__.py test_tutorial
Typer
typer.tiangolo.com βΊ reference βΊ parameters
Parameters - Typer - Tiangolo.com
**Example** ```python def name_callback(value: str): if value != "Deadpool": raise typer.BadParameter("Only Deadpool is allowed") return value @app.command() def main(name: Annotated[str, typer.Argument(callback=name_callback)]): print(f"Hello {name}") ``` """ ), ] = None, metavar: Annotated[ str | None, Doc( """ Customize the name displayed in the help text to represent this CLI Argument.
Calmcode
calmcode.io βΊ course βΊ typer βΊ options
Calmcode - typer: Options
import typer from typing import List from pathlib import Path app = typer.Typer(name="demo", add_completion=False, help="This is a demo app.") @app.command() def talk(text: str = typer.Argument(..., help="The text to type."), repeat: int = typer.Option(1, help="Number of times to repeat."), loud: bool = typer.Option(False, is_flag=True)): """Talks some text below""" if loud: text = text.upper() for _ in range(repeat): print(text) if __name__ == "__main__": app() The talk command can be run in multiple ways now. python cli.py talk "hello there" python cli.py talk "hello there" --repeat 2 python cli.py talk "hello there" --loud python cli.py talk "hello there" --loud --repeat 3
Typer
typer.tiangolo.com βΊ tutorial βΊ options βΊ name
CLI Option Name - Typer
Python 3.10+ - non-Annotated Β· Tip Β· Prefer to use the Annotated version if possible. import typer app = typer.Typer() @app.command() def main(user_name: str = typer.Option(..., "--name")): print(f"Hello {user_name}") if __name__ == "__main__": app() Note Β· "Positional" means that it's not ...
Calmcode
calmcode.io βΊ course βΊ typer βΊ arguments
Calmcode - typer: Arguments
import typer from typing import List from pathlib import Path app = typer.Typer(name="demo", add_completion=False, help="This is a demo app.") @app.command() def hello_world(name): """Say hello""" print(f"hello {name}!") @app.command() def goodbye_world(name): """Say goodbye""" print(f"goodbye {name}!") @app.command() def add(n1: int = typer.Argument(..., help="An integer"), n2: int = typer.Argument(1, help="An integer")): """Add two numbers""" print(n1 + n2) if __name__ == "__main__": app() By adding the argument information we should now see a help text appear for each input but we should now also see proper addition taking place instead of string concatenation. python cli.py add --help python cli.py add 1 1 Β·
Typer
typer.tiangolo.com βΊ tutorial βΊ arguments βΊ default
CLI Arguments with Default - Typer
And we pass it as the first function argument to typer.Argument(). ... The word "factory" in default_factory is just a fancy way of saying "function that will create the default value". ... // Check the help $ uv run python main.py --help Usage: main.py [OPTIONS] [name] Arguments: name [default: (dynamic)] Options: --help Show this message and exit.
Typer
typer.tiangolo.com βΊ tutorial βΊ first-steps
First Steps - Typer
β</font> <font color="#A5A5A1">β°ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ―</font> // There are now 2 CLI arguments, name and lastname // Now pass a single name argument $ uv run python main.py Camila <font color="#F4BF75">Usage: </font>main.py [OPTIONS] {name} {lastname} <font color="#A5A5A1">Try </font><font color="#44919F">'main.py </font><font color="#44919F"><b>--help</b></font><font color="#44919F">'</font><font color="#A
GitHub
github.com βΊ fastapi βΊ typer
GitHub - fastapi/typer: Typer, build great CLIs. Easy to code. Based on Python type hints. Β· GitHub
β β°ββββββββββββββββββββββββββββββββββββββββββββββββββββ― // Now pass the 'name' argument $ uv run python main.py Camila Hello Camila // It works! π Β· Note: you can also call this same script with the typer command, but you don't need to. This was the simplest example possible.
Top answer 1 of 2
1
from typing import List, Optional
import typer
def main(device: Optional[List[str]] = typer.Option(None)):
if not device:
print("No provided devices")
raise typer.Abort()
for d in device:
print(f"Processing device: {d}")
if __name__ == "__main__":
typer.run(main)
And then it can be used like in:
$ ./my_cli --device 1 --device 2
Take a look at the documentation.
If the only input for the CLI is a list of devices, you can simplify it to using arguments instead. Then it could be used like:
$ ./my_cli 1 2
2 of 2
-2
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():
print(f"This file exists: {path.name}")
print(celebration)
if __name__ == "__main__":
typer.run(main)
Typer
typer.tiangolo.com
Typer - Typer
β β°ββββββββββββββββββββββββββββββββββββββββββββββββββββ― // Now pass the 'name' argument $ uv run python main.py Camila Hello Camila // It works! π Β· Note: you can also call this same script with the typer command, but you don't need to. This was the simplest example possible.
Rahulpai
rahulpai.co.uk βΊ smart-clis-with-typer.html
Smart CLIs with Typer - Rahul Pai
June 5, 2023 - from typing import Optional import typer def main(name: str, age: Optional[int] = None): message = f"Hello {name}" if age is not None: message = f"{message}, age {age}" print(message) if __name__ == "__main__": typer.run(main) You can run both of these with python app.py NAME --age AGE.
Medium
medium.com βΊ @hayata-yamamoto βΊ introduction-to-typer-a-powerful-cli-tool-for-python-developers-780c9fd87c19
Introduction to Typer: A Powerful CLI Tool for Python Developers | by Hayata Yamamoto | Medium
June 5, 2025 - import time from typing import Optional import typer from rich import print, progress, prompt app = typer.Typer() # Callback definition: https://typer.tiangolo.com/tutorial/commands/callback/ @app.callback(help="App callback definition") def callback( arg1: str = typer.Argument(..., help="Required argument for the entire app"), option1: bool = typer.Option(default=False, help="Optional argument for the entire app"), ) -> None: print(f"{arg1=}") print(f"{option1=}") # Required arguments: https://typer.tiangolo.com/tutorial/commands/arguments/β¦