FastAPI StreamingResponse がジェネレーター関数でストリーミングされない
FastAPI の StreamingResponse は、データが利用可能になったときにクライアントにストリーミングして戻すことを目的としています。ただし、ジェネレーター関数を使用すると、StreamingResponse が期待どおりに動作しないという報告があります。この記事では、この問題の潜在的な原因を調査し、解決策を提供します。
ブロック操作とジェネレーター関数
Python のジェネレーター関数は、次のような値のシーケンスを定義できます。一度に1つずつ収穫しました。ただし、ブロック操作 (time.sleep() など) がジェネレーター関数内で実行される場合、イベント ループがブロックされ、FastAPI がクライアントにデータをストリーミングできなくなる可能性があります。
Def vs. Async Def
FastAPI は、ジェネレーター関数が def 構文を使用するか、async def 構文を使用するかに基づいて、StreamingResponse を異なる方法で処理します。ジェネレーター関数が async def 構文を使用して定義されている場合、FastAPI はそれが非同期ジェネレーターであると想定し、スレッド プールまたはタスク プールで実行します。ただし、ジェネレーター関数が def 構文を使用している場合、FastAPI はそれをブロッキング ジェネレーターとして認識し、 iterate_in_threadpool() を使用して別のスレッドで実行します。
推奨アプローチ
操作のブロックを回避し、適切なストリーミングを確保するには、非同期ジェネレーター関数 (async def) を使用することをお勧めします。必要に応じて、ブロック操作は外部スレッド プールで実行し、イベント ループの中断を避けるために待機する必要があります。
応答メディア タイプ
場合によっては、ブラウザーがMIME タイプをチェックするためのバッファ テキスト/プレーン応答。これを防ぐには、text/event-stream、application/json などの別のメディア タイプを指定するか、X-Content-Type-Options ヘッダーを nosniff に設定することをお勧めします。
Example
ストリーミング データのジェネレーター関数を備えた動作する FastAPI アプリの例を次に示します。
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")
結論
ブロック操作を回避することによって、非同期ジェネレーター関数を使用し、適切なメディア タイプを指定すると、FastAPI StreamingResponse が意図したとおりに動作することを確認し、データをクライアントに効率的にストリーミングできます。
以上がFastAPI の StreamingResponse がジェネレーター関数でストリーミングされないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。