FastAPI StreamingResponse streamt nicht mit Generatorfunktion
StreamingResponse von FastAPI soll Daten zurück an den Client streamen, sobald sie verfügbar sind. Es gab jedoch Berichte darüber, dass StreamingResponse bei der Verwendung von Generatorfunktionen nicht wie erwartet funktionierte. In diesem Artikel werden die möglichen Ursachen dieses Problems untersucht und eine Lösung bereitgestellt.
Blockierungsoperationen und Generatorfunktionen
Generatorfunktionen in Python können eine Folge von Werten definieren ergab einen nach dem anderen. Wenn jedoch eine Blockierungsoperation (z. B. time.sleep()) innerhalb einer Generatorfunktion ausgeführt wird, kann sie die Ereignisschleife blockieren und so verhindern, dass FastAPI Daten an den Client streamt.
Def vs. Async Def
FastAPI behandelt StreamingResponse unterschiedlich, je nachdem, ob die Generatorfunktion die def- oder async def-Syntax verwendet. Wenn die Generatorfunktion mithilfe der asynchronen Def-Syntax definiert ist, geht FastAPI davon aus, dass es sich um einen asynchronen Generator handelt, und führt ihn in einem Thread-Pool oder Task-Pool aus. Wenn die Generatorfunktion jedoch die Def-Syntax verwendet, erkennt FastAPI sie als blockierenden Generator und verwendet iterate_in_threadpool(), um sie in einem separaten Thread auszuführen.
Empfohlener Ansatz
Um blockierende Vorgänge zu vermeiden und ein ordnungsgemäßes Streaming sicherzustellen, wird die Verwendung einer asynchronen Generatorfunktion (async def) empfohlen. Bei Bedarf sollten alle Blockierungsvorgänge in einem externen Thread-Pool ausgeführt und abgewartet werden, um eine Unterbrechung der Ereignisschleife zu vermeiden.
Antwortmedientyp
In einigen Fällen können Browser dies tun Puffern Sie Text-/einfache Antworten, um den MIME-Typ zu überprüfen. Um dies zu verhindern, empfiehlt es sich, einen anderen Medientyp anzugeben, z. B. text/event-stream, application/json, oder den X-Content-Type-Options-Header auf nosniff zu setzen.
Beispiel
Hier ist ein Beispiel einer funktionierenden FastAPI-App mit einer Generatorfunktion für Streaming-Daten:
from fastapi import FastAPI, StreamingResponse, Request from fastapi.responses import HTMLResponse import asyncio app = FastAPI() @app.get("/stream") async def streaming_data(request: Request): def generate_data(): for i in range(10): yield b'some fake data\n\n' await asyncio.sleep(0.5) return StreamingResponse(generate_data(), media_type="text/event-stream")
Fazit
Durch die Vermeidung blockierender Vorgänge Durch die Verwendung asynchroner Generatorfunktionen und die Angabe des entsprechenden Medientyps können Sie sicherstellen, dass FastAPI StreamingResponse wie vorgesehen funktioniert, sodass Sie Daten effizient an Clients streamen können.
Das obige ist der detaillierte Inhalt vonWarum streamt StreamingResponse von FastAPI nicht mit Generatorfunktionen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!