Lección 3 de 25 · Lectura y práctica
Crear Eventos de Inicio y Cierre para Gestión de Recursos
Tipo de lección: VideoConcepto claveLos eventos de inicio y cierre en FastAPI son hooks que permiten ejecutar código específico cuando tu aplicación se inicia o se detiene. Piensa en ellos como el protocolo de encendido y apagado.
Del concepto a la práctica
Taller de esta lección
El ciclo de vida debe expresar qué recurso nace con la aplicación y cuándo se libera. Un cliente HTTP compartido para consultar un catálogo editorial no debe abrirse por petición. La gestión correcta evita sesiones huérfanas y hace observable el orden de preparación y cierre.
Ejemplo resuelto
Un contexto de vida útil crea app.state.catalog_client al iniciar, registra un estado ready y cierra el cliente al salir. Una ruta solo lee ese recurso desde request.app.state.
El patrón recomendado actual es lifespan; no combines este parámetro con los antiguos manejadores startup/shutdown. Este doble local comprueba limpieza incluso cuando falla el uso:
from contextlib import asynccontextmanager
from fastapi import FastAPI
@asynccontextmanager
async def lifespan(app: FastAPI):
app.state.events = ["open"]
try:
yield
finally:
app.state.events.append("close")
app = FastAPI(lifespan=lifespan)Para activar el ciclo en pruebas utiliza with TestClient(app) as client:; construir el cliente sin contexto no es una prueba equivalente.
Pruébalo
Implementa un gestor
lifespancon contexto asíncrono.Inicializa un cliente falso que registre
opened=True.Ejecuta la aplicación dentro del contexto de prueba.
Comprueba que al salir quede
closed=True.
Comprueba tu resultado
La secuencia observable debe ser open, uso de ruta y close, exactamente una vez por ciclo.
Error frecuente: crear el cliente global al importar el módulo. Corrígelo trasladando su creación al ciclo de vida y comprobando que importar la aplicación no abra recursos.

Mapa de prácticaEl navegador envía una solicitud a la API. El servidor valida la operación y consulta los datos; después devuelve una respuesta que el navegador puede mostrar. La base de datos se comunica con el servidor y no directamente con el navegador.
Ver la infografía en tamaño completo ↗Tipo de lección: Video
Concepto clave
Los eventos de inicio y cierre en FastAPI son hooks que permiten ejecutar código específico cuando tu aplicación se inicia o se detiene. Piensa en ellos como el protocolo de encendido y apagado de una fábrica: al arrancar, verificas que todas las máquinas estén operativas y cargas los materiales necesarios; al cerrar, aseguras que todo quede limpio y los recursos liberados para evitar fugas o daños.
En el contexto de desarrollo backend, estos eventos son cruciales para la gestión de recursos como conexiones a bases de datos, pools de clientes HTTP, o servicios externos. Sin ellos, podrías enfrentar problemas como conexiones huérfanas que consumen memoria o servicios que no se desconectan correctamente, llevando a inestabilidad en producción. El evento de inicio (startup) se ejecuta una vez, justo antes de que FastAPI comience a aceptar solicitudes, mientras que el evento de cierre (shutdown) corre cuando la aplicación se detiene, idealmente liberando todo lo adquirido.
Cómo funciona en la práctica
FastAPI proporciona decoradores integrados para registrar funciones como eventos. Para el inicio, usas @app.on_event("startup"), y para el cierre, @app.on_event("shutdown"). Estos decoradores se aplican a funciones asíncronas o síncronas que realizan tareas específicas. Por ejemplo, al iniciar, podrías establecer una conexión a PostgreSQL y crear un pool reutilizable; al cerrar, cerrarías ese pool y desconectarías cualquier cliente de Redis.
Un flujo típico implica: 1) Definir las funciones de evento con lógica clara y manejos de errores, 2) Registrar estas funciones usando los decoradores en tu instancia de FastAPI, y 3) Asegurar que las operaciones sean atómicas y no bloqueen el ciclo de vida de la aplicación. En entornos avanzados, esto se combina con inyección de dependencias para recursos compartidos, optimizando el rendimiento y la escalabilidad.
Codigo en accion
Aquí un ejemplo funcional que muestra cómo configurar eventos para gestionar una conexión a una base de datos y un cliente de caché:
from fastapi import FastAPI
import asyncpg
import aioredis
from contextlib import asynccontextmanager
# Configuración inicial sin eventos (ANTES)
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hola Mundo"}
# Refactorización con eventos (DESPUÉS)
# Usamos lifespan para un manejo más moderno y limpio
@asynccontextmanager
async def lifespan(app: FastAPI):
# Evento de inicio: conectar a PostgreSQL y Redis
print("Iniciando aplicación...")
app.state.db_pool = await asyncpg.create_pool(
"postgresql://user:pass@localhost/dbname"
)
app.state.redis = await aioredis.from_url("redis://localhost")
yield
# Evento de cierre: cerrar conexiones
print("Cerrando aplicación...")
await app.state.db_pool.close()
await app.state.redis.close()
app = FastAPI(lifespan=lifespan)
@app.get("/")
async def root():
# Usar recursos en endpoints
async with app.state.db_pool.acquire() as connection:
result = await connection.fetch("SELECT * FROM items")
return {"data": result}Este código demuestra la transición de una app básica a una con gestión robusta de recursos, usando el método recomendado lifespan para un control más fino.
Errores comunes
- No manejar excepciones en eventos: Si una conexión falla al iniciar, la app podría arrancar en un estado inconsistente. Siempre incluye try-except para registrar errores y fallar rápido si es crítico.
- Bloquear el evento de inicio con operaciones síncronas largas: Esto retrasa el arranque de la API. Usa funciones asíncronas o ejecuta tareas pesadas en segundo plano.
- Olvidar liberar recursos en el cierre: Conexiones a BD o sockets abiertos pueden causar fugas de memoria. Asegúrate de que cada adquisición en el inicio tenga su liberación correspondiente.
- Usar eventos para lógica de negocio: Los eventos son para gestión de recursos, no para procesar datos de usuarios. Evita mezclar responsabilidades.
- Ignorar el orden de ejecución: En apps complejas, múltiples eventos pueden registrarse; define dependencias claras si un recurso necesita otro para inicializar.
Checklist de dominio
- ¿Puedes configurar eventos de inicio y cierre usando tanto decoradores como el método lifespan?
- ¿Sabes integrar al menos dos tipos de recursos externos (ej., BD y caché) en estos eventos?
- ¿Implementas manejo de errores robusto para fallos durante la inicialización o cierre?
- ¿Eres capaz de refactorizar una app existente para incluir gestión de recursos vía eventos?
- ¿Puedes explicar la diferencia entre eventos síncronos y asíncronos en este contexto?
- ¿Verificas que todos los recursos se liberen correctamente en simulaciones de cierre?
- ¿Documentas los eventos y sus propósitos en tu código para mantenibilidad?
Implementar eventos de ciclo de vida para un microservicio con FastAPI y MongoDB
En este ejercicio, crearás una API avanzada que gestione conexiones a MongoDB y un cliente de email usando eventos de inicio y cierre. Sigue estos pasos:
- Crea un nuevo proyecto FastAPI e instala las dependencias:
fastapi,uvicorn,motor(para MongoDB asíncrono), yaiohttp(para cliente HTTP). - Define una función
lifespanusando@asynccontextmanagerque, al iniciar, establezca una conexión a MongoDB (usando Motor) y un cliente aiohttp para enviar emails. - En el evento de inicio, verifica que la conexión a MongoDB sea exitosa; si falla, lanza una excepción para evitar que la app arranque. Para el cliente aiohttp, configura un timeout de 10 segundos.
- Registra estos recursos en
app.statepara acceso global en los endpoints. - Crea un endpoint
POST /itemsque inserte un documento en MongoDB y, en paralelo, use el cliente aiohttp para simular un email de notificación (puede ser un log). - En el evento de cierre, cierra ambas conexiones de manera segura, asegurándote de que no queden tareas pendientes.
- Prueba la app iniciándola con uvicorn, ejecutando una solicitud al endpoint, y luego deteniéndola para verificar que los recursos se liberen (usa logs para confirmar).
Pistas
- Recuerda que Motor requiere un manejo asíncrono; usa 'await' al conectar y cerrar.
- Para el cliente aiohttp, considera usar 'aiohttp.ClientSession' y cerrarlo en el cierre.
- Agrega prints o logs en cada fase del lifespan para depurar el flujo de eventos.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.
Sigue con Dominio Profesional de FastAPI: Construcción de APIs Escalables y Seguras
Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.
Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.