8. Segundo proyecto práctico (Python + FastAPI)

Objetivo del tema

Guiar la construcción de un servicio HTTP con Python y FastAPI, incorporando pruebas con Pytest y aprovechando el flujo actual del Codex CLI para iterar sobre el código y validar resultados.

8.1 Plan del proyecto

Partiremos de un entorno limpio, definiremos un endpoint /health, escribiremos pruebas y cerraremos la iteración con ayuda de Codex.

Preparar entorno

Crear entorno virtual o perfil uv, instalar FastAPI, Uvicorn y Pytest.

Diseñar API

Definir app FastAPI y la respuesta JSON del endpoint /health.

Agregar pruebas

Validar con Pytest que el endpoint responde con código 200 y estructura esperada.

Iterar con Codex

Usar el CLI para refinar el código, ejecutar pruebas y dejar registro de la sesión.

8.2 Preparar el entorno local

Asegúrate de tener Python 3.10 o superior. Un entorno virtual evita que las dependencias del proyecto afecten a otros trabajos.

python --version
python -m venv .venv

# Windows
.\\.venv\\Scripts\\activate
# macOS / Linux
source .venv/bin/activate

pip install --upgrade pip
pip install fastapi uvicorn pytest httpx

Si prefieres uv, la equivalencia es:

uv venv
source .venv/bin/activate  # uv crea el mismo directorio .venv
uv pip install fastapi uvicorn pytest httpx

8.3 Estructura básica de la aplicación

Crea la carpeta del proyecto y los archivos principales. Usa el bloque según tu plataforma:

# macOS / Linux
mkdir -p app tests
touch app/__init__.py app/main.py tests/test_health.py

# Windows (PowerShell)
New-Item -ItemType Directory -Path app, tests -Force | Out-Null
New-Item -ItemType File -Path app/__init__.py, app/main.py, tests/test_health.py -Force | Out-Null

Define la API en app/main.py:

from datetime import datetime, timezone

from fastapi import FastAPI

app = FastAPI()


@app.get("/health")
def health_check():
    """Entrega el estado del servicio y una marca de tiempo en formato ISO."""
    return {
        "status": "ok",
        "timestamp": datetime.now(timezone.utc).isoformat(),
    }


# Punto de entrada opcional para ejecutar con `python -m app.main`
if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)

8.4 Pruebas con Pytest

En tests/test_health.py usamos el cliente de pruebas integrado en FastAPI para validar el contrato del endpoint.

from datetime import datetime

from fastapi.testclient import TestClient

from app.main import app

client = TestClient(app)


def test_health_returns_ok_payload():
    response = client.get("/health")

    assert response.status_code == 200

    body = response.json()
    assert body["status"] == "ok"
    assert "timestamp" in body

    # Verifica que el timestamp sea ISO-8601.
    datetime.fromisoformat(body["timestamp"])

El último paso dispara una excepción si el formato de la marca temporal no es válido, complementando la aserción principal.

8.5 Ejecutar y validar la API Manualmente

Antes de involucrar al agente, comprueba el comportamiento del servicio.

uvicorn app.main:app --reload --port 8000
curl http://localhost:8000/health

Detén Uvicorn con Ctrl + C cuando termines. Este paso garantiza que las pruebas automatizadas no encuentren el puerto ocupado.

8.6 Iterar con Codex CLI

Las versiones recientes de Codex giran en torno a la interfaz interactiva. Inicia una sesión y describe el objetivo:

codex --full-auto "Crear API /health con FastAPI, agregar Pytest y documentar cambios"

El agente revisará el repositorio, sugerirá modificaciones y mostrará los diffs antes de aplicarlos. Si quieres aprobar cada comando o edición, ejecuta:

codex --sandbox workspace-write --ask-for-approval on-request "Configura FastAPI con Pytest y crea /health"

Desde la sesión puedes solicitar tareas concretas («Genera el test para /health», «Ejecuta pytest -q», «Propón manejo de errores para excepciones»). Usa /approvals para cambiar el modo de aprobación y /status para ver el sandbox activo. Si necesitas pausar, retoma el hilo con codex resume --last o indicando el identificador de la sesión.

Tip: Cuando pidas nuevas mejoras, resume lo que ya existe («Tenemos FastAPI con /health y pruebas básicas, ahora agrega logging estructurado»). Codex aprovechará el contexto para producir diffs más precisos.

8.7 Validar resultados con Codex

Dentro de la sesión interactiva pide: «Ejecuta pytest -q y resume la salida». Así quedó registrado en el flujo de Codex, cumpliendo el rol que en versiones anteriores asumía codex run. Si prefieres automatizarlo desde la terminal, usa el modo no interactivo:

codex exec --full-auto "Corre pytest -q y detalla los resultados"

El agente te devolverá el resumen de la ejecución y mantendrá un log en la conversación. Repite la iteración hasta que las pruebas sean estables y las decisiones de diseño queden documentadas.

Cuando finalices, solicita /status para validar el estado del repositorio o abre otra terminal y ejecuta git status. Comunica en la sesión que la tarea quedó resuelta; la transcripción servirá como evidencia del proceso.

Checklist de validación antes de hacer commit
Aspecto Preguntas de control Acción recomendada
Servicio ¿El endpoint /health responde con 200 y JSON? Ejecuta uvicorn + curl o una herramienta como httpie.
Pruebas ¿Pytest cubre la respuesta y posibles errores? Añade casos negativos (p. ej., simulando excepciones) si tu equipo lo requiere.
Codex CLI ¿Quedó registrada la ejecución de pruebas y los cambios propuestos? Usa el hilo de Codex para resumir resultados y solicita /status antes de cerrar.
Git ¿El commit solo incluye archivos necesarios? Revisa git status, elimina restos temporales y redacta un mensaje claro.

8.8 Conclusión

Con FastAPI y Pytest, Codex CLI actúa como copiloto para documentar decisiones, automatizar pruebas y mantener la calidad del repositorio. El flujo que construiste aquí se puede extender a módulos más complejos, servicios asíncronos o despliegues empaquetados en contenedores, manteniendo siempre la combinación de iteración guiada y validaciones reproducibles.