Usando `async def` vs `def` en FastAPI y probando llamadas bloqueantes.
tl;dr
Como traductor de español que se especializa en documentos de TI, mi tarea consiste en traducir el siguiente texto al español sin traducir el código ni la salida en markdown.
- ¿Cuál de las opciones a continuación es el flujo de trabajo correcto en
fastapi
? - ¿Cómo se prueba programáticamente si una llamada es realmente bloqueante (además de hacerlo manualmente desde el navegador)? ¿Hay alguna extensión de “prueba de estrés” para
uvicorn
ofastapi
?
Tengo varios puntos finales en el servidor fastapi
(actualmente usando uvicorn
) que tienen llamadas bloqueadoras largas de código Python sincrónico normal. A pesar de la documentación (https://fastapi.tiangolo.com/async/), todavía no tengo claro si debería usar exclusivamente def
, async def
o mezclar ambas para mis funciones.
Hasta donde lo entiendo, tengo tres opciones, asumiendo que:
python
def some_long_running_sync_function():
...
Opción 1: use consistentemente def
solo para puntos finales
@app.get("route/to/endpoint")
def endpoint<em>1:
some</em>long<em>running</em>sync_function()
@app.post("route/to/another/endpoint")
def endpoint_2:
...
<h3>Opción 2: use consistentemente <code>async def</code> solamente y ejecute el código sincrónico bloqueador en el executor</h3>
<p>“`python
import asyncio
@app.get(“route/to/endpoint”)
async def endpoint1:
loop = asyncio.geteventloop()
await loop.runinexecutor(None, somelongrunningsync_function)
@app.post(“route/to/another/endpoint”)
async def endpoint_2:
…
Opción 3: mezclar def
y async def
según las llamadas subyacentes
```python
import asyncio
@app.get("route/to/endpoint")
def endpoint<em>1:
# el punto final está llamando al código sincrónico que no se puede esperar
some</em>long<em>running</em>sync_function()
@app.post("route/to/another/endpoint")
async def endpoint_2:
# este código se puede esperar, así que puedo usar async
...
davy.ai
Respuestas
fastapi
dependería del tipo de función que se esté llamando. Si la función es síncrona, se debe usardef
para el punto final. Si es una función asíncrona, se debe usarasync def
para el punto final. Si la función es síncrona con IO de bloqueo, se debe usarasync def
y el IO de bloqueo se ejecutará en un executor usandoloop.run_in_executor
.locust
oJMeter
. Actualmente no está disponible una extensión de prueba de estrés parauvicorn
ofastapi
.