ホームページ >バックエンド開発 >Python チュートリアル >同時 FastAPI/Uvicorn アプリケーションでダウンストリーム HTTP リクエストを行うときに「H11._util.LocalProtocolError」を回避するにはどうすればよいですか?
Uvicorn/FastAPI でのダウンストリーム HTTP リクエストの処理
FastAPI/Uvicorn を使用して API エンドポイントを構築する場合、ダウンストリーム HTTP リクエストを行うのが一般的です。ただし、複数の同時リクエストを処理する場合、開発者は次のエラーに遭遇する可能性があります:
H11._util.LocalProtocolError: can't handle event type ConnectionClosed when role=SERVER and state=SEND_RESPONSE
このエラーは、FastAPI のデフォルトのリクエスト セッションが完全にはスレッドセーフではないために発生します。この課題を克服するには、別のアプローチを採用する必要があります。
非同期 HTTP リクエストに Httpx を使用する
解決策の 1 つは、非同期リクエストを提供する httpx ライブラリを使用することです。 API。 request.Session() の代わりに httpx.AsyncClient() を使用できます。このクライアントでは、基盤となる TCP 接続が再利用されるため、同じホストへの同時リクエストが可能になります。
FastAPI では、起動時に AsyncClient を初期化し、シャットダウン時に閉じるようにライフスパン ハンドラーを定義できます。例:
@asynccontextmanager async def lifespan(app: FastAPI): async with httpx.AsyncClient() as client: yield {'client': client} # Add the client to the app state
エンドポイントでは、request.state.client を使用してクライアントにアクセスできます。次のようにダウンストリーム リクエストを作成できます。
@app.get('/') async def home(request: Request): client = request.state.client req = client.build_request('GET', 'https://www.example.com') r = await client.send(req, stream=True) return StreamingResponse(r.aiter_raw(), background=BackgroundTask(r.aclose))
ストリーミング応答と非ストリーミング レスポンス
ダウンストリーム レスポンスはさまざまな方法でクライアントに送信できます。応答をストリーミングしたい場合は、ジェネレーターを使用して応答データを非同期にループする StreamingResponse を作成できます。それ以外の場合は、r.json()、PlainTextResponse、またはカスタム Response を使用できます。
Httpx を使用する利点
httpx を使用すると、次のような利点があります。
httpx を活用することで、開発者はスレッドに遭遇することなく、FastAPI/Uvicorn アプリケーション内でダウンストリーム HTTP リクエストを効果的に行うことができます。安全性の問題。これにより、信頼性が高くスケーラブルな API 動作が保証されます。
以上が同時 FastAPI/Uvicorn アプリケーションでダウンストリーム HTTP リクエストを行うときに「H11._util.LocalProtocolError」を回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。