StreamingResponse がジェネレーター関数でストリーミングされない
FastAPI は、クライアントに応答を段階的に送信する StreamingResponse クラスを提供します。ただし、場合によっては、この機能が期待どおりに動作しない可能性があります。
根本原因の調査
提供された FastAPI コードと問題の説明を分析した結果、次のことが判明しました。考えられる原因はいくつかあります:
1.データ リクエストでの POST リクエストの使用:
POST リクエストの使用は、サーバーからのデータのリクエストには適していません。代わりに、この目的には GET リクエストを使用することをお勧めします。
2.認証のためのクエリ パラメータの使用:
クエリ パラメータを介して auth_key などの機密認証情報を送信することは安全ではありません。代わりに、認証にヘッダーまたは Cookie を使用することを検討してください。
3.ブロッキング ジェネレーター関数:
StreamingResponse のジェネレーター関数は def (async def ではない) で定義されており、FastAPI イベント ループ内でブロッキングの問題が発生する可能性があります。
4.行ベースのチャンク:
リクエストの iter_lines() は、応答データを一度に 1 行ずつ繰り返します。応答に改行が存在しない場合、データは増分的に出力されません。
5. MIME スニッフィング:
一部のブラウザ (Chrome など) は、テキスト/プレーン レスポンスをバッファリングして、表示する前にプレーンテキスト コンテンツをチェックする場合があります。これにより、ストリーミングが妨げられる可能性があります。
推奨される修正:
1. GET リクエストを使用する:
データの取得に GET リクエストを使用するようにコードをリファクタリングします。
2.安全な認証:
ヘッダーまたは Cookie を使用して、認証資格情報を安全に送信します。
3.非同期ジェネレーター関数:
async def を使用して StreamingResponse のジェネレーター関数を定義します。ジェネレーター内でブロック操作が必要な場合は、外部スレッド プールを使用して実行します。
4.チャンクベースのチャンキング:
チャンク内の応答データを反復処理するには、iter_lines() の代わりに iter_content() を使用します。適切なチャンク サイズを指定します。
5. MIME スニッフィングを無効にする:
StreamingResponse に別のメディア タイプ (application/json や text/event-stream など) を指定するか、X-Content-Type-Options ヘッダーを nosniff に設定することで、MIME スニッフィングを無効にします。
動作例:
次のコードは、ストリーミング機能を備えた動作する FastAPI アプリを示します:
from fastapi import FastAPI, StreamingResponse import asyncio app = FastAPI() async def fake_data_streamer(): for i in range(10): yield b'some fake data\n\n' await asyncio.sleep(0.5) @app.get('/') async def main(): return StreamingResponse(fake_data_streamer(), media_type='text/event-stream')
以上がFastAPI StreamingResponse がジェネレーター関数で動作しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。