返回文章列表

FastAPI 應用程式 Docker 佈署實戰

本文探討如何使用 Docker 和 docker-compose 佈署 FastAPI 應用程式,包含準備 `requirements.txt`、設定環境變數、編寫 Dockerfile 和 docker-compose.yml 等關鍵步驟,並提供 MongoDB 整合的例項,帶領讀者掌握 FastAPI

Web 開發 容器化

在現代 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.yamldocker-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"]

內容解密:

  1. FROM python:3.10:指定基礎映象為 Python 3.10。其他版本的 Python 映象可以在 Docker Hub 上找到。
  2. WORKDIR /app:設定工作目錄為 /app,這有助於組織專案結構。
  3. COPY requirements.txt /app:將本地的 requirements.txt 複製到容器的工作目錄中。
  4. RUN pip install –upgrade pip && pip install -r /app/requirements.txt:升級 pip 並安裝 requirements.txt 中列出的依賴項。
  5. EXPOSE 8080:暴露容器的 8080 埠,以便從本地網路存取應用程式。
  6. COPY ./ /app:將當前目錄下的所有檔案和資料夾複製到容器的工作目錄中。
  7. 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:

內容解密:

  1. api 服務:從當前目錄的 Dockerfile 構建 event-planner-api:latest 映象,並對映主機的 8080 埠到容器的 8080 埠。使用 .env.prod 環境變數檔案。
  2. 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_URLSECRET_KEYDATABASE_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:

在這個組態檔中,我們定義了兩個服務:apidatabaseapi 服務使用當前目錄下的 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
內容解密:
  1. 安裝與設定:本文介紹瞭如何安裝FastAPI和uvicorn,以及如何建立第一個FastAPI應用。
  2. 路由與請求處理:本文詳細介紹瞭如何在FastAPI中定義路徑引數、查詢引數和請求體,並展示瞭如何使用Pydantic模型驗證請求體。
  3. 使用Jinja範本引擎:本文介紹瞭如何安裝Jinja2並在FastAPI應用中渲染範本。
  4. 測試:本文介紹瞭如何使用pytest編寫和執行測試使用案例,以確保API的正確性和穩定性。

透過這些內容,您可以全面瞭解如何使用FastAPI構建和測試REST API。

您的反饋對我們至關重要

現在您已經完成了《使用 FastAPI 構建 Python Web API》這本文,我們非常希望聽到您的想法!如果您從亞馬遜購買了這本文,請點選這裡直接前往亞馬遜上這本文的評論頁面,並分享您的反饋。或者,您也可以在您購買這本文的網站上留下評論。

您的評論對我們和技術社群都非常重要,它將幫助我們確保我們正在提供卓越的內容品質。透過分享您的經驗和想法,您不僅能夠幫助他人做出更明智的購買決定,也能夠為技術社群的發展做出貢獻。

如何提交您的反饋

  1. 存取亞馬遜評論頁面:如果您從亞馬遜購買了這本文,請直接前往亞馬遜上的評論頁面。
  2. 留下您的評論:無論您是在亞馬遜還是其他平台購買的這本文,都請在相應的平台上留下您的評論。
  3. 分享您的想法:詳細描述您對這本文的看法,包括內容、結構、以及它如何幫助您學習或解決問題。

您的每一個反饋都是對我們工作的肯定和鼓勵,也是我們繼續前進的動力。感謝您對 Packt 的支援,我們期待聽到您的聲音!

內容解密: