Hacer requests HTTP asíncronos con httpx
En el desarrollo de APIs modernas, es común necesitar comunicarse con servicios externos durante el procesamiento de una petición. Cuando tu aplicación FastAPI necesita obtener datos de otra API, enviar notificaciones o consultar servicios de terceros, realizar estas operaciones de forma asíncrona es fundamental para mantener el rendimiento.
¿Te está gustando esta lección?
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
httpx es la biblioteca estándar para realizar peticiones HTTP asíncronas en Python. Funciona como el equivalente asíncrono de la popular biblioteca requests
, pero está diseñada específicamente para trabajar con async/await
.
Instalación y configuración básica
Para comenzar a usar httpx en tu proyecto FastAPI, primero debes instalarlo:
pip install httpx
La diferencia principal con requests
es que httpx permite crear clientes asíncronos que no bloquean el hilo de ejecución mientras esperan la respuesta del servidor remoto:
import httpx
from fastapi import FastAPI
app = FastAPI()
@app.get("/usuarios/{user_id}")
async def obtener_usuario_externo(user_id: int):
async with httpx.AsyncClient() as client:
response = await client.get(f"https://jsonplaceholder.typicode.com/users/{user_id}")
return response.json()
El patrón async with
garantiza que el cliente se cierre correctamente después de usar, liberando los recursos de red de manera eficiente.
Métodos HTTP básicos
httpx soporta todos los métodos HTTP estándar con la misma sintaxis familiar de requests, pero en versión asíncrona:
@app.post("/crear-post")
async def crear_post_externo(titulo: str, contenido: str):
async with httpx.AsyncClient() as client:
# POST con datos JSON
post_data = {
"title": titulo,
"body": contenido,
"userId": 1
}
response = await client.post(
"https://jsonplaceholder.typicode.com/posts",
json=post_data
)
return response.json()
@app.put("/actualizar-post/{post_id}")
async def actualizar_post(post_id: int, titulo: str):
async with httpx.AsyncClient() as client:
# PUT para actualizar
response = await client.put(
f"https://jsonplaceholder.typicode.com/posts/{post_id}",
json={"title": titulo}
)
return response.json()
@app.delete("/eliminar-post/{post_id}")
async def eliminar_post(post_id: int):
async with httpx.AsyncClient() as client:
# DELETE
response = await client.delete(
f"https://jsonplaceholder.typicode.com/posts/{post_id}"
)
return {"eliminado": response.status_code == 200}
Manejo de headers y autenticación
Las APIs externas frecuentemente requieren headers específicos o tokens de autenticación. httpx facilita el envío de esta información:
@app.get("/datos-protegidos")
async def obtener_datos_protegidos():
headers = {
"Authorization": "Bearer tu-token-aqui",
"Content-Type": "application/json",
"User-Agent": "MiApp/1.0"
}
async with httpx.AsyncClient() as client:
response = await client.get(
"https://api.ejemplo.com/datos",
headers=headers
)
return response.json()
Para autenticación básica, httpx proporciona un método conveniente:
@app.get("/api-con-auth-basica")
async def consultar_api_con_auth():
async with httpx.AsyncClient() as client:
response = await client.get(
"https://api.ejemplo.com/datos",
auth=("usuario", "contraseña")
)
return response.json()
Combinando múltiples peticiones
Una ventaja significativa de la programación asíncrona es la capacidad de realizar múltiples peticiones HTTP simultáneamente sin bloquear la aplicación:
import asyncio
@app.get("/resumen-usuario/{user_id}")
async def obtener_resumen_usuario(user_id: int):
async with httpx.AsyncClient() as client:
# Realizar múltiples peticiones en paralelo
usuario_task = client.get(f"https://jsonplaceholder.typicode.com/users/{user_id}")
posts_task = client.get(f"https://jsonplaceholder.typicode.com/users/{user_id}/posts")
albums_task = client.get(f"https://jsonplaceholder.typicode.com/users/{user_id}/albums")
# Esperar a que todas las peticiones terminen
usuario_response, posts_response, albums_response = await asyncio.gather(
usuario_task, posts_task, albums_task
)
return {
"usuario": usuario_response.json(),
"posts": posts_response.json(),
"albums": albums_response.json()
}
Cliente reutilizable
Para aplicaciones que realizan múltiples peticiones a la misma API, es más eficiente crear un cliente reutilizable que mantenga las conexiones abiertas:
# Cliente global para reutilizar conexiones
http_client = httpx.AsyncClient(
base_url="https://jsonplaceholder.typicode.com",
headers={"User-Agent": "MiApp/1.0"}
)
@app.get("/posts")
async def listar_posts():
response = await http_client.get("/posts")
return response.json()
@app.get("/posts/{post_id}")
async def obtener_post(post_id: int):
response = await http_client.get(f"/posts/{post_id}")
return response.json()
# Importante: cerrar el cliente al finalizar la aplicación
@app.on_event("shutdown")
async def cerrar_cliente():
await http_client.aclose()
Manejo básico de errores
Es fundamental manejar los errores que pueden ocurrir durante las peticiones HTTP, como problemas de conectividad o respuestas de error del servidor:
from fastapi import HTTPException
@app.get("/usuario-seguro/{user_id}")
async def obtener_usuario_con_manejo_errores(user_id: int):
try:
async with httpx.AsyncClient() as client:
response = await client.get(
f"https://jsonplaceholder.typicode.com/users/{user_id}"
)
# Verificar si la petición fue exitosa
if response.status_code == 404:
raise HTTPException(status_code=404, detail="Usuario no encontrado")
response.raise_for_status() # Lanza excepción si hay error HTTP
return response.json()
except httpx.RequestError:
# Error de conectividad
raise HTTPException(status_code=503, detail="Servicio externo no disponible")
except httpx.HTTPStatusError:
# Error HTTP (4xx, 5xx)
raise HTTPException(status_code=502, detail="Error en servicio externo")
Esta aproximación te permite integrar servicios externos en tus endpoints FastAPI manteniendo la naturaleza asíncrona de tu aplicación, lo que resulta en mejor rendimiento y capacidad de respuesta para tus usuarios.
Aprendizajes de esta lección
- Comprender la importancia de realizar peticiones HTTP asíncronas en FastAPI.
- Aprender a usar httpx para crear clientes asíncronos y realizar solicitudes HTTP.
- Conocer cómo manejar headers y autenticación en peticiones externas.
- Implementar múltiples peticiones concurrentes para optimizar el rendimiento.
- Aplicar técnicas básicas de manejo de errores en peticiones HTTP asíncronas.
Completa FastAPI y certifícate
Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs