1. 什么是 FastAPI?

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于基于标准 Python 类型提示构建 API。它由 Sebastián Ramírez 创建,旨在提供与 Node.js 和 Go 相当的高性能,同时保持 Python 的易用性和开发速度。

核心特性:

  • 极高性能:基于 Starlette(用于 Web 微服务)和 Pydantic(用于数据验证),性能可与 Node.js 和 Go 媲美。
  • 快速开发:代码自动补全和类型检查支持大幅提升开发效率。
  • 自动生成交互式 API 文档:内置 Swagger UI 和 ReDoc,无需额外编写文档。
  • 基于标准:完全兼容 OpenAPI(原 Swagger)和 JSON Schema。
  • 类型安全:利用 Python 类型提示进行数据验证、序列化和文档生成。

2. 安装与环境准备

确保已安装 Python 3.7+,然后使用 pip 安装 FastAPI 和 ASGI 服务器(如 Uvicorn):

pip install fastapi uvicorn[standard]

验证安装:

import fastapi
print(fastapi.__version__)  # 应输出版本号,如 0.104.0

3. 第一个 FastAPI 应用

创建一个名为 main.py 的文件,写入以下代码:

from fastapi import FastAPI

# 创建 FastAPI 实例
app = FastAPI()

# 定义根路径路由
@app.get("/")
def read_root():
    return {"message": "Hello, FastAPI!"}

# 带路径参数的路由
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

运行应用:

uvicorn main:app --reload
  • main:模块名(即 main.py)。
  • app:FastAPI 实例变量名。
  • --reload:开发时启用热重载。

访问 http://127.0.0.1:8000 将看到 {"message":"Hello, FastAPI!"}

4. 自动交互式 API 文档

启动服务后,FastAPI 自动生成两种交互式文档:

  1. Swagger UI:访问 http://127.0.0.1:8000/docs

    • 可交互测试所有 API 端点。
    • 显示请求/响应模型、参数说明。
  2. ReDoc:访问 http://127.0.0.1:8000/redoc

    • 提供更美观、阅读友好的文档视图。

无需手动编写,文档基于代码中的类型提示和注释自动生成。

5. 请求与响应模型

使用 Pydantic 模型定义数据结构,FastAPI 会自动处理验证、序列化和文档。

示例:定义数据模型与 POST 请求

from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional

app = FastAPI()

# 定义 Item 模型
class Item(BaseModel):
    name: str
    price: float
    is_offer: Optional[bool] = False

# GET 请求示例
@app.get("/items/{item_id}")
def get_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

# POST 请求示例
@app.post("/items/")
def create_item(item: Item):
    return {"item_name": item.name, "item_price": item.price}

说明:

  • Item 继承 BaseModel,字段使用类型提示。
  • FastAPI 会自动验证请求体是否符合 Item 模型。
  • 无效数据将返回 422 错误及详细原因。

6. 路径参数、查询参数与请求体

FastAPI 清晰区分不同类型的参数:

参数类型 声明方式 示例
路径参数 在路径中声明,作为函数参数 @app.get("/items/{item_id}")
查询参数 函数参数中非路径参数的默认值或 Optional q: str = None
请求体 使用 Pydantic 模型作为参数 item: Item

混合使用示例:

@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item, q: str = None):
    return {
        "item_id": item_id,
        "item_name": item.name,
        "item_price": item.price,
        "q": q
    }

7. 依赖注入系统

FastAPI 的依赖注入系统可复用代码、管理共享逻辑(如数据库会话、认证)。

简单依赖示例:

from fastapi import Depends, FastAPI

app = FastAPI()

# 定义一个依赖函数
def common_parameters(q: str = None, skip: int = 0, limit: int = 100):
    return {"q": q, "skip": skip, "limit": limit}

# 在路由中使用依赖
@app.get("/items/")
def read_items(commons: dict = Depends(common_parameters)):
    return commons

高级用法: 依赖可嵌套、缓存,并用于认证、数据库连接等场景。

8. 错误处理

FastAPI 内置 HTTPException,可自定义错误响应。

from fastapi import FastAPI, HTTPException

app = FastAPI()

items = {"foo": "The Foo Wrestlers"}

@app.get("/items/{item_id}")
def read_item(item_id: str):
    if item_id not in items:
        raise HTTPException(status_code=404, detail="Item not found")
    return {"item": items[item_id]}

也可使用自定义异常处理器实现统一错误格式。

9. 中间件与 CORS

添加中间件(如记录请求时间):

import time
from fastapi import FastAPI, Request

app = FastAPI()

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

启用 CORS(跨域资源共享):

from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],  # 前端地址
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

10. 部署建议

开发环境: 使用 uvicorn main:app --reload

生产环境:

  1. 使用 Gunicorn + Uvicorn Workers(Linux/macOS):
    pip install gunicorn
    gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
    
  2. Docker 部署:创建 Dockerfile
    FROM python:3.9
    WORKDIR /code
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    COPY . .
    CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
    
  3. 平台即服务:可直接部署到 Vercel、Railway、Heroku、AWS Lambda(通过 Mangum)等。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐