首頁 > 後端開發 > Python教學 > 在並發 FastAPI/Uvicorn 應用程式中發出下游 HTTP 請求時,如何避免「H11._util.LocalProtocolError」?

在並發 FastAPI/Uvicorn 應用程式中發出下游 HTTP 請求時,如何避免「H11._util.LocalProtocolError」?

Patricia Arquette
發布: 2024-12-07 19:25:17
原創
248 人瀏覽過

How Can I Avoid `H11._util.LocalProtocolError` When Making Downstream HTTP Requests in a Concurrent FastAPI/Uvicorn Application?

在 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 有幾個好處:

  • 非同步 API,用於高效處理並發請求。
  • 持久連接池以提高效能。
  • 控制連線池大小。
  • 與 FastAPI 的生命週期處理程序和端點輕鬆整合。

透過利用 httpx,開發人員可以有效地FastAPI/Uvicorn 應用程式中的下游 HTTP 請求不會遇到執行緒安全性問題。這確保了可靠且可擴展的 API 行為。

以上是在並發 FastAPI/Uvicorn 應用程式中發出下游 HTTP 請求時,如何避免「H11._util.LocalProtocolError」?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板