Loading...
Loading...
Typer best practices and conventions. Use when working with Typer CLIs. Keeps Typer code clean and up to date with the latest features and patterns, updated with new versions. Write new code or refactor and update old code.
npx skill4agent add fastapi/typer typerpip install typeruv pip install typertyperpyproject.tomltyper-slimtyper-clityperTypertyper.runimport typer
app = typer.Typer()
@app.command()
def hello():
print(f"Hello World")
if __name__ == "__main__":
app()# DO NOT DO THIS: Not extensible. Use Typer() instead.
import typer
def main():
print(f"Hello World")
if __name__ == "__main__":
typer.run(main)python main.pypython main.py hellopython main.py --helpno_args_is_helpTrueTyper()AnnotatedAnnotatedfrom typing import Annotated
import typer
app = typer.Typer()
@app.command()
def hello(name: Annotated[str, typer.Argument()] = "World"):
# Note that name is an optional Argument, as a default is provided
print(f"Hello {name}")
if __name__ == "__main__":
app()python main.py
python main.py Rick# DO NOT DO THIS: old style. Use Annotated instead.
@app.command()
def main(name: str = typer.Argument(default="World")):
# Note that name is an optional Argument, as a default is provided
print(f"Hello {name}")# DO NOT DO THIS: old style. Use Annotated without a default value instead.
@app.command()
def main(name: str = typer.Argument(default=...)):
# Note that name is now a required Argument
print(f"Hello {name}")user_name--user-namefrom typing import Annotated
import typer
app = typer.Typer()
@app.command()
def main(user_name: Annotated[str, typer.Option()]):
# On the CLI, the required user name can be specified with --user-name
print(f"Hello {user_name}")
if __name__ == "__main__":
app()typer.Optionfrom typing import Annotated
import typer
app = typer.Typer()
@app.command()
def main(user_name: Annotated[str, typer.Option("--name", "-n")]):
# On the CLI, the required user name can be specified with -n or --name
print(f"Hello {user_name}")
if __name__ == "__main__":
app()python main.py -n "Rick"
python main.py --name "Morty"from typing import Annotated
import typer
app = typer.Typer()
@app.command()
def main(user: Annotated[list[str] | None, typer.Option()] = None):
if not user:
print(f"No users provided!")
raise typer.Abort()
for u in user:
print(f"Processing user: {u}")
if __name__ == "__main__":
app()python main.py --user Rick --user Morty --user Summerfrom rich import print
print("[bold red]Alert![/bold red] [green]Portal gun[/green] shooting! :boom:")from typing import Annotated
import typer
app = typer.Typer(rich_markup_mode="rich")
@app.command()
def create(
username: Annotated[
str, typer.Argument(help="The username to be [green]created[/green]")
],
):
"""
[bold green]Create[/bold green] a new [italic]shiny[/italic] user. :sparkles:
This requires a [underline]username[/underline].
"""
print(f"Creating user: {username}")
@app.command(help="[bold red]Delete[/bold red] a user with [italic]username[/italic].")
def delete(
username: Annotated[
str, typer.Argument(help="The username to be [red]deleted[/red]")
],
):
"""
Some internal utility function to delete.
"""
print(f"Deleting user: {username}")
if __name__ == "__main__":
app()rich_markup_modeNoneTyper()rich_markup_mode"markdown"from typing import Annotated
import typer
app = typer.Typer(rich_markup_mode="markdown")
@app.command(help="**Delete** a user with *username*.")
def delete(
username: Annotated[
str, typer.Argument(help="The username to be **deleted** :boom:")
],
):
print(f"Deleting user: {username}")
if __name__ == "__main__":
app()OptionArgumentexpose_valueshell_completeshow_choiceserrorsprompt_requiredis_flagflag_valueallow_from_autoenv