在現代 Web 開發中,容器化佈署已成為主流趨勢。本文將引導讀者使用 Docker 和 docker-compose 佈署 FastAPI 應用程式,確保應用程式在不同環境中具有一致性與可移植性。首先,我們需要整理專案的依賴關係,並將其列於 requirements.txt 檔案中,以便在 Docker 容器中正確安裝。接著,設定必要的環境變數,例如資料函式庫連線字串和應用程式金鑰,確保應用程式正常運作。接下來,我們將編寫 Dockerfile,定義如何構建應用程式的 Docker 映像,其中包含基礎映像選擇、程式碼複製、依賴安裝和啟動命令等步驟。最後,使用 docker-compose.yml 檔案,定義應用程式所需的多個服務,例如 FastAPI 應用程式本身和 MongoDB 資料函式庫,並設定它們之間的互動關係,簡化容器的協調和管理,實作更便捷的佈署流程。
測試 FastAPI 應用程式
在前一章中,我們成功地為事件規劃 API 中的端點編寫了測試。本章將介紹如何使用 Docker 和 docker-compose 在本地佈署 FastAPI 應用程式。同時,也會提供一些外部資源,用於將應用程式佈署到您選擇的無伺服器平台。
技術需求
佈署前的準備
在佈署應用程式之前,我們需要確保所有必要的設定都已就緒,包括更新 requirements.txt 檔案中的依賴項、組態環境變數等。
管理依賴項
在前面的章節中,我們安裝了 beanie 和 pytest 等套件。這些套件並未包含在 requirements.txt 檔案中,該檔案是我們應用程式的依賴項管理器。保持 requirements.txt 檔案的更新非常重要。
在 Python 中,可以使用 pip freeze 命令檢索開發環境中使用的套件清單。該命令傳回直接安裝的套件和每個套件的子依賴項。幸運的是,可以手動維護 requirements.txt 檔案,使我們能夠僅列出主要套件,從而簡化依賴項管理。
(venv)$ pip freeze
anyio==3.5.0
asgi-lifespan==1.0.1
asgiref==3.5.0
attrs==21.4.0
bcrypt==3.2.2
cffi==1.15.0
python-multipart==0.0.5
...
更新 requirements.txt 檔案
讓我們手動填寫 requirements.txt 檔案,包含我們將要使用的套件:
fastapi==0.78.0
bcrypt==3.2.2
beanie==1.11.1
email-validator==1.2.1
httpx==0.22.0
Jinja2==3.0.3
motor==2.5.1
passlib==1.7.4
pytest==7.1.2
python-multipart==0.0.5
python-dotenv==0.20.0
python-jose==3.3.0
sqlmodel==0.0.6
uvicorn==0.17.6
組態環境變數
我們在第 6 章「連線到資料函式庫」中使用了環境變數。環境變數可以在佈署期間注入,如下一節所示。
注意事項
請注意,環境變數需要妥善處理,並保持在版本控制系統(如 GitHub)之外。
使用 Docker 佈署
現在,我們已經完成了佈署前的必要步驟。接下來,讓我們使用 Docker 在本地佈署應用程式。
#### 內容解密:
本章節中,我們學習瞭如何使用 Docker 和 docker-compose 在本地佈署 FastAPI 應用程式。同時,也介紹瞭如何更新 requirements.txt 檔案中的依賴項和組態環境變數。這些步驟對於成功佈署應用程式至關重要。
# 使用官方 Python 映像作為基礎映像
FROM python:3.9-slim
# 設定工作目錄為 /app
WORKDIR /app
# 複製 requirements.txt 檔案到工作目錄
COPY requirements.txt .
# 安裝依賴項
RUN pip install --no-cache-dir -r requirements.txt
# 複製應用程式碼到工作目錄
COPY . .
# 暴露容器內的 8000 連線埠
EXPOSE 8000
# 使用 uvicorn 執行應用程式
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
#### 內容解密:
此 Dockerfile 用於建立 FastAPI 應用程式的 Docker 映像。它首先使用官方 Python 映像作為基礎映像,然後設定工作目錄、複製 requirements.txt 檔案、安裝依賴項、複製應用程式碼、暴露連線埠,最後使用 uvicorn 執行應用程式。
使用 Docker 佈署 FastAPI 應用程式
在第一章「FastAPI 入門」中,我們已經介紹了 Docker 和 Dockerfile 的基礎知識。在本文中,我們將為事件規劃 API 編寫 Dockerfile。
Docker 簡介
Docker 是目前最流行的容器化技術。容器是一種自包含的系統,包含了軟體包、程式碼和依賴項,使其能夠在不同的環境中執行,而幾乎不受執行環境的影響。Docker 利用 Dockerfile 進行容器化過程。
Docker 不僅可用於本地開發,也可用於將應用程式佈署到生產環境。本章節將重點介紹本地佈署,同時也會提供官方的連結,以便佈署到雲端服務。
對於管理具有多個容器的應用程式(例如應用程式容器和資料函式庫容器),我們使用 docker-compose 工具。docker-compose 是一個用於管理多容器 Docker 應用程式的工具,其組態檔案通常為 docker-compose.yaml。docker-compose 工具隨著 Docker 引擎一同安裝。
編寫 Dockerfile
Dockerfile 包含了一組用於構建 Docker 映象的指令。構建好的 Docker 映象可以分發到私有或公開的倉函式庫,佈署到雲端伺服器(如 AWS 和 Google Cloud),並在不同的作業系統上透過建立容器來使用。
現在,讓我們為事件規劃 API 建立一個 Dockerfile。在專案目錄中,建立一個名為 Dockerfile 的檔案:
(venv)$ touch Dockerfile
Dockerfile 的內容如下:
FROM python:3.10
WORKDIR /app
COPY requirements.txt /app
RUN pip install --upgrade pip && pip install -r /app/requirements.txt
EXPOSE 8080
COPY ./ /app
CMD ["python", "main.py"]
內容解密:
- FROM python:3.10:指定基礎映象為 Python 3.10。其他版本的 Python 映象可以在 Docker Hub 上找到。
- WORKDIR /app:設定工作目錄為
/app,這有助於組織專案結構。 - COPY requirements.txt /app:將本地的
requirements.txt複製到容器的工作目錄中。 - RUN pip install –upgrade pip && pip install -r /app/requirements.txt:升級 pip 並安裝
requirements.txt中列出的依賴項。 - EXPOSE 8080:暴露容器的 8080 埠,以便從本地網路存取應用程式。
- COPY ./ /app:將當前目錄下的所有檔案和資料夾複製到容器的工作目錄中。
- CMD [“python”, “main.py”]:指定容器啟動時執行的命令,即執行
main.py。
Dockerfile 中的每組指令都會被構建成一個獨立的層。Docker 會智慧地快取每個層,以減少構建時間並避免重複工作。如果某個層沒有變化,Docker 就會直接使用之前構建好的層。
建立 .dockerignore 檔案
在構建映象之前,讓我們先建立一個 .dockerignore 檔案:
(venv)$ touch .dockerignore
.dockerignore 的內容如下:
venv
.env
.git
內容解密:
.dockerignore 檔案用於指定哪些檔案或目錄應該被忽略,不被複製到 Docker 映象中。這裡我們忽略了虛擬環境資料夾、env 檔案和 Git 資料夾。
建構 Docker 映象
在專案根目錄下執行以下命令來構建應用程式的 Docker 映象:
(venv)$ docker build -t event-planner-api .
這個命令告訴 Docker 使用當前目錄中的 Dockerfile 來構建一個名為 event-planner-api 的映象。
提取 MongoDB 映象
接下來,我們需要提取 MongoDB 的官方映象:
(venv)$ docker pull mongo
內容解密:
docker pull 命令用於從 Docker Hub 下載指定的映象。這裡我們下載了 MongoDB 的官方映象,用於建立一個獨立的資料函式庫容器。
編寫 docker-compose.yml
現在,我們有了 API 的映象和 MongoDB 的映象,接下來編寫 docker-compose.yml 檔案來管理我們的應用程式佈署:
(venv)$ touch docker-compose.yml
docker-compose.yml 的內容如下:
version: "3"
services:
api:
build: .
image: event-planner-api:latest
ports:
- "8080:8080"
env_file:
- .env.prod
database:
image: mongo
ports:
- "27017"
volumes:
- data:/data/db
volumes:
data:
內容解密:
- api 服務:從當前目錄的 Dockerfile 構建
event-planner-api:latest映象,並對映主機的 8080 埠到容器的 8080 埠。使用.env.prod環境變數檔案。 - database 服務:使用官方的 MongoDB 映象,對映主機的隨機埠到容器的 27017 埠。並將資料持久化到一個名為
data的卷中。
這樣,我們就完成了使用 Docker 和 docker-compose 佈署 FastAPI 應用程式的組態。接下來,可以透過執行 docker-compose up 命令來啟動服務。
使用 Docker 佈署 FastAPI 應用程式
在前面的章節中,我們學習瞭如何建立和測試 FastAPI 應用程式。現在,我們將學習如何使用 Docker 將應用程式佈署到生產環境。
建立環境變數檔
首先,我們需要建立一個環境變數檔 .env.prod,用於儲存應用程式的環境變數。這個檔案將被 Docker Compose 使用。
DATABASE_URL=mongodb://database:27017/planner
SECRET_KEY=NOTSTRONGENOUGH!
在這個檔案中,我們定義了兩個環境變數:DATABASE_URL 和 SECRET_KEY。DATABASE_URL 是 MongoDB 資料函式庫的連線字串,而 SECRET_KEY 是用於簽署 JWT 令牌的金鑰。
內容解密:
DATABASE_URL指定了 MongoDB 資料函式庫的位置和連線方式。SECRET_KEY用於保護應用程式的 JWT 令牌。
編寫 Docker Compose 組態檔
接下來,我們需要編寫一個 Docker Compose 組態檔 docker-compose.yml,用於定義應用程式的服務和依賴關係。
version: '3'
services:
api:
build: .
environment:
- DATABASE_URL=mongodb://database:27017/planner
- SECRET_KEY=NOTSTRONGENOUGH!
ports:
- "8080:8080"
depends_on:
- database
database:
image: mongo
volumes:
- data:/data/db
volumes:
data:
在這個組態檔中,我們定義了兩個服務:api 和 database。api 服務使用當前目錄下的 Dockerfile 建立映像,而 database 服務使用官方的 MongoDB 映像。
內容解密:
api服務依賴於database服務,因此我們使用depends_on指令指定依賴關係。database服務使用volumes指令將資料儲存在持久化卷中。
啟動應用程式
現在,我們可以使用 Docker Compose 啟動應用程式。
docker-compose up -d
這個指令將在背景啟動應用程式的服務。
內容解密:
-d引數指定 Docker Compose 在背景執行服務。
驗證應用程式
啟動應用程式後,我們可以使用 docker ps 指令驗證服務是否正在執行。
docker ps
這個指令將列出正在執行的容器。
內容解密:
docker ps指令用於列出正在執行的容器。
測試應用程式
現在,我們可以使用 curl 指令測試應用程式的 API。
curl -X 'GET' \
'http://localhost:8080/event/' \
-H 'accept: application/json'
這個指令將向應用程式的 /event/ 端點傳送 GET 請求。
內容解密:
-X引數指定請求方法。-H引數指定請求頭。
使用FastAPI構建與測試REST API
簡介
本篇文章將介紹如何使用FastAPI框架構建和測試REST API。我們將探討FastAPI的基本功能、路由、請求和回應處理,並透過實踐示例演示如何實作CRUD(建立、讀取、更新、刪除)操作。此外,我們還將討論如何使用Pydantic模型驗證請求體、使用Jinja範本引擎進行範本渲染,以及如何使用pytest進行單元測試。
FastAPI基礎
安裝與設定
首先,您需要安裝FastAPI和uvicorn,分別用於構建API和執行伺服器。可以使用pip進行安裝:
pip install fastapi uvicorn
建立第一個FastAPI應用
建立一個名為main.py的檔案,並新增以下程式碼:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
執行應用:
uvicorn main:app --reload
存取http://127.0.0.1:8000/即可看到結果。
路由與請求處理
路徑引數
使用Path類別定義路徑引數:
from fastapi import Path
@app.get("/items/{item_id}")
def read_item(item_id: int = Path(..., title="The ID of the item to get")):
return {"item_id": item_id}
查詢引數
使用函式引數定義查詢引數:
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}
請求體
使用Pydantic模型驗證請求體:
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
@app.post("/items/")
def create_item(item: Item):
return item
回應模型
定義回應模型以控制傳回的資料結構:
from pydantic import BaseModel
class ItemResponse(BaseModel):
name: str
price: float
@app.post("/items/", response_model=ItemResponse)
def create_item(item: Item):
return item
使用Jinja範本引擎
安裝Jinja2
pip install jinja2
渲染範本
建立一個名為templates的資料夾,並在其中新增一個名為index.html的範本檔案:
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
</body>
</html>
在FastAPI應用中使用Jinja範本:
from fastapi import Request
from fastapi.templating import Jinja2Templates
templates = Jinja2Templates(directory="templates")
@app.get("/items/{item_id}")
def read_item(request: Request, item_id: int):
return templates.TemplateResponse("index.html", {"request": request, "title": f"Item {item_id}"})
測試
安裝pytest
pip install pytest
編寫測試使用案例
建立一個名為test_main.py的檔案,並新增以下程式碼:
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_read_root():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"Hello": "World"}
執行測試:
pytest
內容解密:
- 安裝與設定:本文介紹瞭如何安裝FastAPI和uvicorn,以及如何建立第一個FastAPI應用。
- 路由與請求處理:本文詳細介紹瞭如何在FastAPI中定義路徑引數、查詢引數和請求體,並展示瞭如何使用Pydantic模型驗證請求體。
- 使用Jinja範本引擎:本文介紹瞭如何安裝Jinja2並在FastAPI應用中渲染範本。
- 測試:本文介紹瞭如何使用pytest編寫和執行測試使用案例,以確保API的正確性和穩定性。
透過這些內容,您可以全面瞭解如何使用FastAPI構建和測試REST API。
您的反饋對我們至關重要
現在您已經完成了《使用 FastAPI 構建 Python Web API》這本文,我們非常希望聽到您的想法!如果您從亞馬遜購買了這本文,請點選這裡直接前往亞馬遜上這本文的評論頁面,並分享您的反饋。或者,您也可以在您購買這本文的網站上留下評論。
您的評論對我們和技術社群都非常重要,它將幫助我們確保我們正在提供卓越的內容品質。透過分享您的經驗和想法,您不僅能夠幫助他人做出更明智的購買決定,也能夠為技術社群的發展做出貢獻。
如何提交您的反饋
- 存取亞馬遜評論頁面:如果您從亞馬遜購買了這本文,請直接前往亞馬遜上的評論頁面。
- 留下您的評論:無論您是在亞馬遜還是其他平台購買的這本文,都請在相應的平台上留下您的評論。
- 分享您的想法:詳細描述您對這本文的看法,包括內容、結構、以及它如何幫助您學習或解決問題。
您的每一個反饋都是對我們工作的肯定和鼓勵,也是我們繼續前進的動力。感謝您對 Packt 的支援,我們期待聽到您的聲音!