在 Uvicorn/FastAPI 中处理下游 HTTP 请求
使用 FastAPI/Uvicorn 构建 API 端点时,通常会发出下游 HTTP 请求。然而,在处理多个并发请求时,开发者可能会遇到错误:
H11._util.LocalProtocolError: can't handle event type ConnectionClosed when role=SERVER and state=SEND_RESPONSE
出现此错误是因为 FastAPI 的默认请求会话不是完全线程安全的。为了克服这一挑战,我们需要采用另一种方法。
使用 Httpx 进行异步 HTTP 请求
一种解决方案是使用 httpx 库,它提供了异步API。我们可以使用 httpx.AsyncClient() 来代替 requests.Session()。该客户端允许对同一主机进行并发请求,因为底层 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中文网其他相关文章!