在我們深入探討 FastAPI 的強大功能之前,我們必須先了解一個核心概念:伺服器與框架之間的溝通標準。今天,我們將深入探討 WSGI 和 ASGI 這兩個重要的協定,它們是連接 Web 伺服器與 Python Web 應用程式(如 FastAPI)之間的橋樑。
讓我們先想像一個使用者(Client)發送 HTTP Request 的流程:
這個流程的關鍵在於第 3 點和第 4 點之間的溝通規範。
WSGI (PEP 3333) 是 Python Web 開發的傳統標準。它的設計非常簡單直接:「一個請求,一個回應」。
WSGI 的運作模式是同步 (Synchronous) 的。當一個請求進來,Application Server 會呼叫我們的 Python 應用程式,然後等待應用程式處理完成並返回一個完整的 HTTP 回應後,才能去處理下一個請求。如果應用程式需要執行一個耗時的 I/O 操作(例如:讀取大型檔案、等待外部 API 回應),整個處理程序都會被阻塞 (Blocking)。
這在傳統的 Web 應用中運作得很好,但對於需要處理大量並行連線、長時間連線(如 WebSocket)或 I/O 密集型的現代應用來說,效率就顯得不足。
隨著 asyncio
的興起,Python 社群需要一個新的標準來支援非同步 Web 框架,於是 ASGI 誕生了。
ASGI 是 WSGI 的精神繼承者,但它天生就是非同步 (Asynchronous) 的。它不僅能處理傳統的 HTTP 請求,還能處理生命週期更長的連線,例如 WebSocket 和 Server-Sent Events (SSE)。
與 WSGI 的「請求-回應」模型不同,ASGI 使用的是一個更靈活的事件模型。一個應用程式不再是單一的可呼叫物件,而是一個 (scope, receive, send)
的結構:
scope
:一個包含連線資訊的字典。receive
:一個 awaitable
,讓應用程式可以接收事件(如 HTTP request body)。send
:一個 awaitable
,讓應用程式可以發送事件(如 HTTP response headers/body)。因為它是非同步的,當一個 ASGI 應用程式在等待 I/O 操作時(例如 await some_api_call()
),它可以將控制權交還給事件循環 (Event Loop),讓伺服器可以去處理其他請求,從而實現高效率的並行處理。
這正是 FastAPI 選擇 ASGI 的原因。FastAPI 建立在 Starlette 之上,而 Starlette 是一個輕量級的 ASGI 框架。這使得 FastAPI 能夠充分利用 async def
的語法,輕鬆地處理大量並行 I/O 密集型任務,這對於 AI 應用(例如等待模型推論、串流回應)來說至關重要。
今天介紹了 WSGI 與 ASGI 這兩個協定,他們都是負責將 HTTP 請求轉換成 Python 應用程式能夠理解的格式。明天我們將介紹實現這些協定的具體伺服器:Uvicorn 和 Gunicorn。