Build Python CLIs with Typer using type hints, commands, options, testing, completion, and packaging-aware guidance.
Use this skill when building or reviewing a Python CLI that should feel like ordinary typed Python code while still getting Click-powered help, completion, and UX.
typer.run()typer.Typer()typer.testing.CliRunnertyper.run(function) for a very small single-command script.app = typer.Typer(...) once the CLI has multiple commands or is
likely to grow.--formal and
--no-formal.Annotated[..., typer.Option(...)] or
Annotated[..., typer.Argument(...)] when you need help text,
prompts, defaults, validation, or richer parameter metadata.no_args_is_help=True is useful when a blank invocation should show
the help page instead of doing nothing.typer command.typer.testing.CliRunner.exit_code, output, and prompt behavior via input=....typer.run(main), you can still
build a test-only Typer() app around that function.import typer
def main(name: str):
print(f"Hello {name}")
if __name__ == "__main__":
typer.run(main)
from typing import Annotated
import typer
app = typer.Typer(no_args_is_help=True)
@app.command()
def hello(name: str):
print(f"Hello {name}")
@app.command()
def goodbye(
name: str,
formal: Annotated[bool, typer.Option(help="Use a formal goodbye")] = False,
):
if formal:
print(f"Goodbye Ms. {name}. Have a good day.")
else:
print(f"Bye {name}!")
if __name__ == "__main__":
app()
from typer.testing import CliRunner
from .main import app
runner = CliRunner()
def test_hello():
result = runner.invoke(app, ["hello", "Camila"])
assert result.exit_code == 0
assert "Hello Camila" in result.output
from typing import Annotated
import typer
from typer.testing import CliRunner
app = typer.Typer()
@app.command()
def subscribe(
email: Annotated[str, typer.Option(prompt="Email address")],
):
print(email)
runner = CliRunner()
def test_prompt():
result = runner.invoke(app, ["subscribe"], input="[email protected]\n")
assert result.exit_code == 0
assert "[email protected]" in result.output
When refining this skill or reviewing advice produced with it:
typer command as failuresCliRunner for ordinary CLI behavior as a warning
sign