En pocas palabras
Biblioteca para crear aplicaciones de terminal (CLI) en Python mediante funciones y anotaciones de tipos, con argumentos, ayuda y autocompletado.
Qué problema resuelve
Código repetitivo para interpretar parámetros y scripts difíciles de utilizar.
Cuándo utilizarlo
Automatización, procesamiento de datos y herramientas internas. Ejemplo: transformar un script en reportes generar --fecha 2026-10-17.
De la idea a la práctica
Funcionamiento, ejemplos y decisiones para pasar al siguiente nivel.
Cómo funciona
Typer utiliza las anotaciones de tipos y los valores predeterminados para construir argumentos y opciones. Los parámetros requeridos pueden ser argumentos; los que tienen valor predeterminado se convierten normalmente en opciones.
Ejemplo: una utilidad de reportes
Con el paquete typer instalado, guarda esto en reportes.py:
import typer
def generar(fecha: str, formato: str = "csv"):
print(f"Reporte de {fecha} en {formato}")
if __name__ == "__main__":
typer.run(generar)
Ejecuta python reportes.py 2026-10-17 --formato json o consulta python reportes.py --help.
Aplicación con subcomandos y opciones anotadas
from datetime import datetime
from enum import Enum
from pathlib import Path
from typing import Annotated
import typer
app = typer.Typer(help="Utilidades de cartera", no_args_is_help=True)
reportes = typer.Typer(help="Generación de reportes")
app.add_typer(reportes, name="reportes")
class Formato(str, Enum):
csv = "csv"
json = "json"
xlsx = "xlsx"
@reportes.command("mora")
def reporte_mora(
fecha: Annotated[datetime, typer.Argument(formats=["%Y-%m-%d"], help="Fecha de corte")],
formato: Annotated[Formato, typer.Option("--formato", "-f")] = Formato.csv,
salida: Annotated[Path, typer.Option(dir_okay=False, writable=True)] = Path("mora.csv"),
pais: Annotated[list[str], typer.Option(help="Puede repetirse")] = ["CO"],
):
"""Genera el reporte de cartera en mora a una fecha de corte."""
if fecha > datetime.now():
typer.secho("La fecha de corte no puede ser futura", fg=typer.colors.RED, err=True)
raise typer.Exit(code=2)
filas = calcular_mora(fecha, pais)
escribir(filas, salida, formato.value)
typer.echo(f"{len(filas)} créditos escritos en {salida}")
@app.command()
def purgar(dias: int = 90, forzar: Annotated[bool, typer.Option(prompt="¿Seguro?")] = False):
"""Elimina archivos temporales antiguos."""
...
if __name__ == "__main__":
app()
cartera reportes mora 2026-09-30 -f json --pais CO --pais MX
cartera --help
cartera --install-completion # autocompletado para bash, zsh, fish, PowerShell
| Tipo de anotación | Comportamiento |
|---|---|
Enum |
Valores permitidos, mostrados en la ayuda |
datetime |
Parseo con los formatos indicados |
Path |
Validación de existencia, tipo y permisos |
list[str] |
Opción repetible |
bool |
Banderas --forzar / --no-forzar |
Pruebas
from typer.testing import CliRunner
from cartera.cli import app
runner = CliRunner()
def test_fecha_futura_falla():
res = runner.invoke(app, ["reportes", "mora", "2099-01-01"])
assert res.exit_code == 2
assert "no puede ser futura" in res.output
Distribución
# pyproject.toml
[project.scripts]
cartera = "cartera.cli:app"
Con uv, uv tool install . (o desde un repositorio git) instala la CLI en un entorno aislado para cualquier persona del equipo. Typer usa Rich para mostrar errores y ayuda con formato, y se integra bien con Pydantic para validar configuración compleja.
Buenas prácticas de CLI
- Salida para humanos en stdout; mensajes de diagnóstico y errores en stderr.
- Códigos de salida distintos por tipo de error, para que los scripts puedan reaccionar.
- Opción
--dry-runen comandos con efectos y confirmación en operaciones destructivas. - Formatos de salida legibles por máquina (
--formato json) para encadenar con otras herramientas.
Criterios de implementación
Agrupa subcomandos cuando crezca la utilidad. Valida fechas y reglas del negocio explícitamente; una cadena tipada como str no valida por sí sola un calendario. Usa códigos de salida para integraciones con scripts.
Continúa en las fuentes
Documentación oficial para verificar detalles y explorar más.