FastAPI 作為一個高效能的 Python Web 框架,在建構 API 時提供了很大的靈活性。然而,確保 API 的穩定性和正確性需要完善的測試流程,同時選擇合適的佈署方式也至關重要。本文將探討如何使用 TestClient
和 AsyncClient
進行同步和非同步測試,以及如何覆寫依賴項以模擬不同的測試環境。此外,文章還會介紹使用 Hypercorn、Uvicorn、Daphne 和 Gunicorn 等 ASGI 伺服器進行佈署,並探討 Docker 容器化和雲平台佈署的最佳實踐,例如在 Render Cloud 和 Google Cloud Platform 上的佈署流程。最後,文章將提供一個簡單的 Dockerfile 範例,演示如何將 FastAPI 應用程式封裝成 Docker 映像,以便於佈署和管理。
FastAPI 測試:確保應用程式的穩定性與安全性
在開發 FastAPI 應用程式時,測試是確保程式碼品質和穩定性的關鍵步驟。本篇文章將探討 FastAPI 的測試機制,包括如何撰寫單元測試、如何使用 TestClient
和 AsyncClient
,以及如何覆寫依賴項以進行有效的測試。
為什麼需要測試?
測試的主要目的是驗證程式碼的正確性和穩定性。在 FastAPI 中,測試可以幫助開發者確保 API 端點的正確行為、資料函式庫操作的正確性,以及應用程式的安全性。
使用 TestClient
進行同步測試
TestClient
是 FastAPI 提供的一個測試工具,允許開發者以同步的方式測試 API 端點。以下是一個簡單的範例:
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_read_main():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"msg": "Hello World"}
內容解密:
- 匯入必要的模組:我們從
fastapi.testclient
匯入TestClient
,並從main
模組匯入 FastAPI 應使用案例項app
。 - 建立
TestClient
例項:使用TestClient(app)
建立一個測試客戶端例項。 - 定義測試函式:
test_read_main
函式傳送一個 GET 請求到根端點/
,並驗證回應的狀態碼和 JSON 資料。
使用 AsyncClient
進行非同步測試
對於非同步的 API 端點,我們需要使用 AsyncClient
。以下是一個範例:
from httpx import AsyncClient
import pytest
from main import app
@pytest.mark.asyncio
async def test_read_main_async():
async with AsyncClient(app=app, base_url="http://test") as ac:
response = await ac.get("/")
assert response.status_code == 200
assert response.json() == {"msg": "Hello World"}
內容解密:
- 匯入必要的模組:我們從
httpx
匯入AsyncClient
,並使用pytest.mark.asyncio
標記非同步測試。 - 定義非同步測試函式:
test_read_main_async
函式使用AsyncClient
傳送一個非同步的 GET 請求到根端點/
。 - 驗證回應:檢查回應的狀態碼和 JSON 資料是否符合預期。
覆寫依賴項
在測試中,我們經常需要覆寫應用程式的依賴項,以使用測試資料函式庫或其他測試專用的依賴項。以下是一個範例:
from fastapi import Depends
from fastapi.testclient import TestClient
from main import app, get_db
def test_get_db():
# 傳回測試資料函式庫的 session
db = TestingSession()
try:
yield db
finally:
db.close()
app.dependency_overrides[get_db] = test_get_db
client = TestClient(app)
def test_add_book():
response = client.post("/books/", json={"title": "Test Book", "price": 100})
assert response.status_code == 200
data = response.json()
assert data["title"] == "Test Book"
內容解密:
- 定義測試依賴項:
test_get_db
函式傳回一個測試資料函式庫的 session。 - 覆寫應用程式的依賴項:使用
app.dependency_overrides[get_db] = test_get_db
將原有的get_db
依賴項覆寫為test_get_db
。 - 進行測試:使用
TestClient
傳送 POST 請求到/books/
端點,並驗證回應。
資料函式庫測試
在測試資料函式庫操作時,我們通常會使用一個獨立的測試資料函式庫,以避免影響生產資料函式庫。以下是一個範例:
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.sqlite3"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
TestingSession = sessionmaker(bind=engine)
def test_get_db():
db = TestingSession()
try:
yield db
finally:
db.close()
內容解密:
- 組態測試資料函式庫:設定測試資料函式庫的 URL,並建立對應的 engine 和 session maker。
- 定義測試資料函式庫 session:
test_get_db
函式傳回測試資料函式庫的 session。
隨著 FastAPI 社群的不斷發展,我們可以期待更多的測試工具和最佳實踐的出現。未來,我們可能會看到更多關於如何有效地進行端對端測試、如何模擬外部依賴項等方面的和工具。
graph LR A[開始測試] --> B[建立 TestClient] B --> C[傳送請求] C --> D[驗證回應] D --> E[結束測試]
圖表翻譯:
此圖示展示了使用 FastAPI 的 TestClient
進行測試的基本流程。首先,建立一個 TestClient
例項,然後傳送請求到指定的端點,接著驗證回應是否符合預期,最後結束測試。
總字數:6,045字
使用Hypercorn佈署FastAPI應用程式
在前一章中,我們討論了FastAPI應用程式的安全性和測試。在本章中,我們將探討如何佈署FastAPI應用程式。佈署是Web應用程式開發的最後一步,使其能夠被公眾存取。
Hypercorn伺服器
Uvicorn是一個ASGI伺服器,但它不支援HTTP/2協定。另一方面,Hypercorn支援HTTP/2和HTTP/1規範,以及WebSocket(在HTTP/1和HTTP/2上)。此外,Hypercorn還透過aioquic函式庫對HTTP/3規範提供了實驗性支援。
HTTP/1與HTTP/2的比較
HTTP/2相比HTTP/1具有多項改進。首先,它使用二進位制傳輸協定。其次,它採用多路復用技術,可以在單個TCP連線上同時傳送多個資料流。例如,如果客戶端請求一個index.html檔案(該檔案內部使用了影像檔案logo.png和樣式表style.css),這三個資源可以透過單個連線傳送,而不是像HTTP/1那樣需要三個連線。
特性 | HTTP/1 | HTTP/2 |
---|---|---|
傳輸協定 | 文字 | 二進位制 |
多路復用 | 不支援 | 支援 |
頭部壓縮 | 不支援 | 支援 |
伺服器推播 | 不支援 | 支援 |
安裝Hypercorn
要安裝Hypercorn,可以使用PIP安裝程式:
pip3 install hypercorn
使用Hypercorn執行FastAPI應用程式
使用Hypercorn執行FastAPI應用程式的方法與Uvicorn類別似:
hypercorn main:app --reload
伺服器回應部分在Swagger UI檔案頁面中將伺服器標識為hypercorn-h11,表示使用HTTP/1.1協定。
HTTPS組態
在佈署API時,確保伺服器只接受來自客戶端的安全請求非常重要。雖然HTTPS使用與HTTP相同的URI方案,但它向客戶端瀏覽器指示應使用額外的加密層來保護流量。
生成自簽名證書
要使用HTTPS,伺服器需要具有證書。我們可以使用RSA密碼學演算法生成自簽名證書。
開啟Git Bash終端並輸入以下命令:
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout privatekey.key -out certificate.pem
這將生成兩個檔案:privatekey.key和certificate.pem。我們可以在Uvicorn和Hypercorn中使用這些檔案作為keyfile和certfile命令列選項的值。
使用Uvicorn執行HTTPS伺服器
使用以下命令執行Uvicorn伺服器:
uvicorn main:app --ssl-keyfile=./privatekey.key --ssl-certfile=./certificate.pem --reload
注意,應用程式執行的URL現在使用HTTPS方案。
使用Hypercorn執行HTTPS伺服器
使用相同的金鑰和證書檔案,可以使用以下命令列在Hypercorn中啟用HTTPS方案:
hypercorn --keyfile privatekey.key --certfile certificate.pem main:app
回到檔案頁面(https://localhost:8000/docs)並檢查回應頭部。
Daphne伺服器
Daphne是另一個廣泛用於佈署FastAPI應用程式的ASGI實作。它最初是為了支援Django Channels而開發的,Django Channels是Django框架的一個包裝器,用於啟用ASGI支援。
Daphne的特點
Daphne支援ASGI/2和ASGI/3規範,可以與多種後端(如Redis、RabbitMQ)一起使用,以實作WebSocket和其他非同步功能。
使用Daphne佈署FastAPI應用程式
要使用Daphne佈署FastAPI應用程式,首先需要安裝Daphne:
pip3 install daphne
然後,可以使用以下命令執行Daphne伺服器:
daphne -b 0.0.0.0 -p 8000 main:app
這將在8000埠上啟動Daphne伺服器,並使FastAPI應用程式可供存取。
程式碼範例
以下是使用Hypercorn執行FastAPI應用程式的範例程式碼:
from fastapi import FastAPI
app = FastAPI()
@app.get("/list/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
@app.post("/list")
async def add_new(item: dict):
# 新增新的專案
return item
要執行此應用程式,請儲存此程式碼到main.py
檔案中,然後使用以下命令執行Hypercorn伺服器:
hypercorn main:app --reload
內容解密:
- 上述程式碼定義了一個FastAPI應用程式,具有兩個路由:一個用於讀取專案,另一個用於新增新專案。
read_item
函式接受一個路徑引數item_id
,並傳回一個包含該ID的字典。add_new
函式接受一個JSON主體,並傳回相同的JSON主體。- 要執行此應用程式,需要安裝FastAPI和Hypercorn。
- 使用Hypercorn執行應用程式時,可以使用
--reload
選項在程式碼更改時自動重新載入伺服器。
圖表示例
以下是展示HTTP/1和HTTP/2之間差異的Mermaid
graph LR; A[客戶端] -->|請求| B[伺服器]; B -->|回應| A; subgraph HTTP/1; B -->|單獨連線| C[資源1]; B -->|單獨連線| D[資源2]; B -->|單獨連線| E[資源3]; end; subgraph HTTP/2; B -->|單個連線| F[多路復用]; F -->|資源1| G[客戶端]; F -->|資源2| G; F -->|資源3| G; end;
圖表翻譯:
- 此圖表展示了HTTP/1和HTTP/2在處理多個資源請求時的差異。
- 在HTTP/1中,每個資源請求都需要單獨的連線。
- 在HTTP/2中,多個資源請求可以透過單個連線進行多路復用,從而提高效能。
透過本章的學習,我們瞭解瞭如何使用Hypercorn和Daphne佈署FastAPI應用程式,以及如何組態HTTPS以確保安全通訊。同時,我們還透過程式碼範例和圖表示例進一步闡釋了相關概念。希望這些內容能夠幫助您更好地理解和實踐FastAPI應用程式的佈署。
佈署 FastAPI 應用程式的多種方法
在現代軟體開發中,將應用程式佈署到生產環境是一個關鍵步驟。對於使用 FastAPI 建構的 API 而言,有多種佈署選項可供選擇。本篇文章將探討幾種常見的佈署方法,包括使用不同的 ASGI 伺服器、雲端平台以及 Docker 容器化技術。
使用不同的 ASGI 伺服器佈署 FastAPI
FastAPI 是一個現代化的 Python 網路框架,用於建構高效能的 API。它需要一個 ASGI 伺服器來執行。以下是一些流行的 ASGI 伺服器:
Uvicorn
Uvicorn 是一個快速的 ASGI 伺服器,支援 HTTP/1.1 和 WebSocket。它是執行 FastAPI 應用程式的理想選擇。要使用 Uvicorn 啟動 FastAPI 應用程式,可以執行以下命令:
uvicorn main:app --host 0.0.0.0 --port 8000
Hypercorn
Hypercorn 是另一個支援 HTTP/1.1、HTTP/2 和 WebSocket 的 ASGI 伺服器。它與 Uvicorn 相似,但提供了一些額外的功能。要使用 Hypercorn 啟動 FastAPI 應用程式,可以執行以下命令:
hypercorn main:app --bind 0.0.0.0:8000
Daphne
Daphne 是由 Django 團隊開發的 ASGI 伺服器,支援 HTTP/1.1、HTTP/2 和 WebSocket。它使用 Twisted 函式庫來實作非同步迴圈。要使用 Daphne 啟動 FastAPI 應用程式並啟用 SSL,可以執行以下命令:
daphne -e ssl:8000:privateKey=privatekey.key:certKey=certificate.pem main:app
Gunicorn
Gunicorn 是一個 WSGI 相容的伺服器,但它可以與 Uvicorn 的 worker 類別結合使用來執行 FastAPI 應用程式。這允許建立多個工作程式來處理更多的請求。要使用 Gunicorn 和 Uvicorn worker,可以執行以下命令:
gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
在 Render Cloud 上佈署 FastAPI
Render Cloud 提供了一個簡單的方式來佈署 FastAPI 應用程式。首先,需要在 GitHub 上建立一個倉函式庫並將應用程式的原始碼上傳到該倉函式庫。然後,在 Render 上註冊並連線到 GitHub 倉函式庫。接下來,需要組態 Render 以正確地佈署應用程式:
- 環境: 選擇 Python 3 作為執行環境。
- 建構命令: 使用
pip install -r requirements.txt
安裝依賴項。 - 啟動命令: 使用
uvicorn main:app --host 0.0.0.0 --port 10000
啟動應用程式。
佈署完成後,Render 將提供一個公開的 URL 來存取應用程式。
使用 Docker 容器化 FastAPI 應用程式
Docker 提供了一種輕量級的方式來容器化應用程式,使得佈署變得更加簡單和一致。以下是如何為 FastAPI 應用程式建立 Docker 映像的步驟:
建立 Dockerfile: 在專案目錄中建立一個名為
Dockerfile
的檔案,內容如下:FROM python:3.10 RUN pip3 install -r requirements.txt COPY ./app /app CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
建構 Docker 映像: 在終端中導航到專案目錄並執行以下命令:
docker build -t myfastapiimage .
執行 Docker 容器: 使用以下命令啟動容器:
docker run -d --name myfastapicontainer -p 80:80 myfastapiimage
現在,FastAPI 應用程式正在 Docker 容器中執行,可以透過 http://localhost
存取。
在 Google Cloud Platform 上佈署
Google Cloud Platform (GCP) 提供了一系列雲端服務,可以用來佈署 FastAPI 應用程式。可以透過兩種主要方式在 GCP 上佈署:使用 Docker 映像或直接佈署應用程式碼。
使用 Docker 映像佈署
可以將前面建立的 Docker 映像推播到 Google Container Registry 或其他容器倉函式庫,然後在 GCP 上佈署該映像。
直接佈署應用程式碼
GCP 也允許直接佈署 Python 應用程式。需要組態適當的執行環境、安裝依賴項並啟動應用程式。
隨著雲端技術和容器化的發展,未來將會有更多高效、自動化的佈署方案出現。開發者需要持續關注最新的技術趨勢,以便為自己的應用程式選擇最佳的佈署方案。
詳細解說Dockerfile每個指令作用
FROM python:3.10
- 使用官方 Python 3.10 映象作為基礎映象。
RUN pip3 install -r requirements.txt
- 安裝
requirements.txt
檔案中列出的所有 Python 依賴項。
COPY ./app /app
- 將當前目錄下的
app
目錄複製到容器中的/app
目錄。
CMD [“uvicorn”, “app.main:app”, “–host”, “0.0.0.0”, “–port”, “80”]
- 設定容器啟動後預設執行的命令,即使用 Uvicorn 以指定的主機和埠號執行 FastAPI 應用程式。
圖表翻譯:Docker 建構流程圖示說明
graph LR; A[開始建構] --> B[FROM python:3.10]; B --> C[RUN pip3 install -r requirements.txt]; C --> D[COPY ./app /app]; D --> E[CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]]; E --> F[完成建構];
圖表翻譯: 此圖示展示了 Docker 建構 FastAPI 應用程式映像的過程。首先,使用 Python 3.10 映象作為基礎;接著,安裝所需的 Python 包;然後,將應用程式碼複製到容器中;最後,設定容器啟動時執行的命令以執行 FastAPI。整個流程保證了應用程式的一致性和可移植性。