fastapi-expert

fastapi-expert

熱門

使用 FastAPI 與 Pydantic V2 建置高效能非同步 Python API 時使用。可用於建立 REST 端點、定義 Pydantic 模型、實作身份驗證流程、設定非同步 SQLAlchemy 資料庫操作、新增 JWT 身份驗證、建置 WebSocket 端點,或生成 OpenAPI 文件。觸發詞:FastAPI、Pydantic、async Python、Python API、REST API Python、SQLAlchemy async、JWT authentication、OpenAPI、Swagger Python。

1.1萬星標
962分支
更新於 2026/5/20
SKILL.md
唯讀
名稱
fastapi-expert
描述

使用 FastAPI 與 Pydantic V2 建置高效能非同步 Python API 時使用。可用於建立 REST 端點、定義 Pydantic 模型、實作身份驗證流程、設定非同步 SQLAlchemy 資料庫操作、新增 JWT 身份驗證、建置 WebSocket 端點,或生成 OpenAPI 文件。觸發詞:FastAPI、Pydantic、async Python、Python API、REST API Python、SQLAlchemy async、JWT authentication、OpenAPI、Swagger Python。

FastAPI Expert

精通非同步 Python、Pydantic V2,以及使用 FastAPI 開發生產級 API 的專業技能。

何時使用此 Skill

  • 使用 FastAPI 建置 REST API
  • 實作 Pydantic V2 驗證 Schema
  • 設定非同步資料庫操作
  • 實作 JWT 身份驗證與授權
  • 建立 WebSocket 端點
  • 最佳化 API 效能

核心工作流程

  1. 需求分析 — 識別端點、資料模型與身份驗證需求
  2. 設計 Schema — 建立用於驗證的 Pydantic V2 模型
  3. 實作開發 — 撰寫具備妥善依賴注入(Dependency Injection)的非同步端點
  4. 強化安全 — 加入身份驗證、授權與流量限制(Rate Limiting)
  5. 測試驗證 — 使用 pytest 和 httpx 撰寫非同步測試;完成每組端點後執行 pytest,並至 /docs 驗證 OpenAPI 文件

每一步驟的檢查點: 繼續下一步前,請先確認 Schema 驗證無誤、端點回傳預期的 HTTP 狀態碼,且 /docs 正確反映預期的 API 介面。

最小完整範例

將 Schema + 端點 + 依賴注入整合於單一模組中:

# schemas.py
from pydantic import BaseModel, EmailStr, field_validator, model_config

class UserCreate(BaseModel):
    model_config = model_config(str_strip_whitespace=True)

    email: EmailStr
    password: str
    name: str | None = None

    @field_validator("password")
    @classmethod
    def password_strength(cls, v: str) -> str:
        if len(v) < 8:
            raise ValueError("Password must be at least 8 characters")
        return v

class UserResponse(BaseModel):
    model_config = model_config(from_attributes=True)

    id: int
    email: EmailStr
    name: str | None = None
# routers/users.py
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Annotated

from app.database import get_db
from app.schemas import UserCreate, UserResponse
from app import crud

router = APIRouter(prefix="/users", tags=["users"])

DbDep = Annotated[AsyncSession, Depends(get_db)]

@router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def create_user(payload: UserCreate, db: DbDep) -> UserResponse:
    existing = await crud.get_user_by_email(db, payload.email)
    if existing:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Email already registered")
    return await crud.create_user(db, payload)
# crud.py
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models import User
from app.schemas import UserCreate
from app.security import hash_password

async def get_user_by_email(db: AsyncSession, email: str) -> User | None:
    result = await db.execute(select(User).where(User.email == email))
    return result.scalar_one_or_none()

async def create_user(db: AsyncSession, payload: UserCreate) -> User:
    user = User(email=payload.email, hashed_password=hash_password(payload.password), name=payload.name)
    db.add(user)
    await db.commit()
    await db.refresh(user)
    return user

JWT 身份驗證程式碼片段

# security.py
from datetime import datetime, timedelta, timezone
from jose import JWTError, jwt
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from typing import Annotated

SECRET_KEY = "read-from-env"  # use os.environ / settings
ALGORITHM = "HS256"
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/token")

def create_access_token(subject: str, expires_delta: timedelta = timedelta(minutes=30)) -> str:
    payload = {"sub": subject, "exp": datetime.now(timezone.utc) + expires_delta}
    return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)

async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]) -> str:
    try:
        data = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        subject: str | None = data.get("sub")
        if subject is None:
            raise ValueError
        return subject
    except (JWTError, ValueError):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials")

CurrentUser = Annotated[str, Depends(get_current_user)]

參考指南

根據情境載入詳細指南:

主題 參考文件 載入時機
Pydantic V2 references/pydantic-v2.md 建立 Schema、資料驗證、model_config
SQLAlchemy references/async-sqlalchemy.md 非同步資料庫、模型、CRUD 操作
端點 references/endpoints-routing.md APIRouter、依賴項、路由設定
身份驗證 references/authentication.md JWT、OAuth2、get_current_user
測試 references/testing-async.md pytest-asyncio、httpx、fixtures
Django 遷移 references/migration-from-django.md 從 Django/DRF 遷移至 FastAPI

限制與規範

必須做到 (MUST DO)

  • 在所有地方使用型別提示(Type Hints,FastAPI 必需)
  • 使用 Pydantic V2 語法(field_validatormodel_validatormodel_config
  • 使用 Annotated 模式進行依賴注入
  • 所有 I/O 操作均使用 async/await
  • 使用 X | None 替代 Optional[X]
  • 回傳適當的 HTTP 狀態碼
  • 為端點撰寫文件(自動生成 OpenAPI)

嚴禁切記 (MUST NOT DO)

  • 使用同步資料庫操作
  • 略過 Pydantic 驗證
  • 以明文儲存密碼
  • 在回應中洩漏敏感資料
  • 使用 Pydantic V1 語法(@validatorclass Config
  • 不當混用同步與非同步程式碼
  • 硬編碼(Hardcode)設定值

輸出範本

實作 FastAPI 功能時,請提供:

  1. Schema 檔案(Pydantic 模型)
  2. 端點檔案(包含端點的 Router)
  3. CRUD 操作(若涉及資料庫)
  4. 關鍵設計決策的簡要說明

知識參考

FastAPI, Pydantic V2, async SQLAlchemy, Alembic migrations, JWT/OAuth2, pytest-asyncio, httpx, BackgroundTasks, WebSockets, dependency injection, OpenAPI/Swagger

Documentation