Imagina que tu API necesita hacer varias llamadas a servicios externos que tardan mucho (varios segundos o minutos) y las hace una tras otra, lo que aumenta el tiempo total de respuesta y afecta la experiencia del usuario.
Mejorar el rendimiento realizando esas llamadas de forma concurrente, es decir, en paralelo, para reducir el tiempo total de espera.
asyncio: librería estándar de Python para programación asíncrona.httpx: cliente HTTP async que permite hacer solicitudes concurrentes fácilmente.Acontinuación, un ejemplo de Flask que utiliza httpx para realizar solicitudes concurrentes y mide el tiempo total de respuesta.
from flask import Flask, jsonify
import asyncio
import httpx
import time
app = Flask(__name__)
# Simula llamada a una API externa lenta (por ejemplo, 5 segundos)
async def llamada_lenta_api(ciudad):
print(f"Consultando API externa para {ciudad}...")
await asyncio.sleep(5) # simula retraso IO
return { "ciudad": ciudad, "datos": f"Info para {ciudad}" }
# Llama concurrentemente a varias APIs (simuladas)
async def obtener_datos_concurrentes(ciudades):
tareas = [llamada_lenta_api(ciudad) for ciudad in ciudades]
resultados = await asyncio.gather(*tareas)
return resultados
@app.route("/datos_concurrentes")
async def datos_concurrentes():
ciudades = ["bogota", "medellin", "cali", "barranquilla"]
inicio = time.time()
resultados = await obtener_datos_concurrentes(ciudades)
fin = time.time()
return {
"tiempo_total_segundos": round(fin - inicio, 2),
"resultados": resultados
}
if __name__ == "__main__":
app.run(debug=True) Funciones async
llamada_lenta_api es una función async que simula una llamada lenta con await asyncio.sleep(5).
Esto representa la espera por I/O (llamada externa real).
Concurrencia con asyncio.gather
En obtener_datos_concurrentes, generamos tareas para cada ciudad y las ejecutamos todas a la vez con asyncio.gather.
Esto permite que las esperas se solapen y no se ejecuten una tras otra.
Ruta async en Flask
Flask 2.0+ permite definir rutas async (async def).
En /datos_concurrentes, llamamos a la función concurrente y medimos el tiempo total.
Tiempo total Aunque cada llamada tarda 5 segundos, todas las llamadas concurrentes tardan aproximadamente 5 segundos en total, no 20.
No olvides instalar httpx:
pip install httpx Luego, puedes probar el ejemplo.
python app.py Abre tu navegador o usa curl para llamar la ruta:
http://localhost:5000/datos_concurrentes Deberías ver que el tiempo total ronda los 5 segundos, no la suma (20 segundos).