一、FastAPI 核心定义

1. 什么是 FastAPI?

FastAPI 是一个现代、高性能的 Python Web 框架,基于 Starlette(异步网络框架)和 Pydantic(数据校验)构建,主打:

  • 极速的性能(可与 Node.js、Go 媲美);
  • 自动生成交互式 API 文档(Swagger UI / ReDoc);
  • 强类型支持,结合 Python 类型注解实现数据校验;
  • 异步支持,兼容同步代码;
  • 极简的语法,上手成本低。

2. FastAPI 核心组件 & 基础用法

(1)环境准备

首先安装依赖:

pip install fastapi uvicorn  # uvicorn 是 ASGI 服务器,用于运行 FastAPI 应用

(2)最小化 FastAPI 应用(核心结构)

# main.py
from fastapi import FastAPI

# 1. 核心:创建 FastAPI 应用实例
app = FastAPI(
    title="我的第一个 FastAPI 应用",  # API 文档标题
    description="FastAPI 学习笔记示例",  # API 文档描述
    version="1.0.0"  # 版本
)

# 2. 路由:定义接口(路径操作)
# @app.方法("路径") 装饰器:绑定 HTTP 方法和路径
@app.get("/")  # GET 请求,路径为根路径
def read_root():
    """根路径接口,返回简单字典"""
    return {"message": "Hello FastAPI"}

# 带路径参数的接口
@app.get("/items/{item_id}")
# 类型注解:指定 item_id 为 int 类型,FastAPI 会自动校验并转换
def read_item(item_id: int, q: str | None = None):
    """
    获取单个商品
    :param item_id: 商品ID(必填,int 类型)
    :param q: 可选查询参数(str 类型,默认 None)
    """
    return {"item_id": item_id, "q": q}

# 运行命令:uvicorn main:app --reload
# --reload:开发模式,代码修改后自动重启

(3)核心概念解析

概念 作用
FastAPI() 创建应用实例,是整个项目的核心入口,可配置文档、跨域、中间件等全局属性
路径操作装饰器 @app.get()/@app.post()/@app.put() 等,绑定 HTTP 方法和接口路径
路径操作函数 装饰器下方的函数,处理接口的业务逻辑,返回值会自动序列化为 JSON
类型注解 不仅是提示,FastAPI 会根据注解做参数校验、类型转换、文档生成
自动文档 运行后访问 http://127.0.0.1:8000/docs(Swagger)或 http://127.0.0.1:8000/redoc

(4)请求方法 & 数据接收

FastAPI 支持所有 HTTP 标准方法:GET/POST/PUT/DELETE/PATCH 等,核心数据接收方式:

from fastapi import FastAPI, Query, Path, Body
from pydantic import BaseModel

app = FastAPI()

# 1. 查询参数(Query):通过 Query 做高级校验
@app.get("/items/")
def get_items(
    skip: int = Query(0, ge=0, description="跳过的数量"),  # ge=0:必须 >=0
    limit: int = Query(10, le=100, description="限制的数量")  # le=100:必须 <=100
):
    return {"skip": skip, "limit": limit}

# 2. 路径参数(Path):通过 Path 做高级校验
@app.get("/items/{item_id}")
def get_item(
    item_id: int = Path(..., gt=0, description="商品ID"),  # ...:必填,gt=0:必须 >0
    name: str = Query(..., description="商品名称")
):
    return {"item_id": item_id, "name": name}

# 3. 请求体(Body):通过 Pydantic 模型接收 POST/PUT 等请求的JSON数据
class Item(BaseModel):
    name: str
    price: float
    is_offer: bool | None = None  # 可选字段

@app.post("/items/")
def create_item(item: Item):  # 接收 Pydantic 模型作为请求体
    return {"item_name": item.name, "item_price": item.price * 1.1}

二、Pydantic 模块

1. 什么是 Pydantic?

Pydantic 是 Python 中用于数据校验和设置管理的库,核心基于 Python 类型注解,能:

  • 自动校验输入数据的类型、格式、范围;
  • 转换数据类型(如字符串转整数、日期字符串转 datetime 对象);
  • 提供清晰的错误提示;
  • 支持嵌套模型、自定义校验规则;
  • 是 FastAPI 数据校验的底层核心。

2. Pydantic 核心用法

(1)基础模型定义(BaseModel)

Pydantic 的核心是 BaseModel,所有数据模型都继承它:

from pydantic import BaseModel, ValidationError
from datetime import datetime

# 定义数据模型
class User(BaseModel):
    # 基础字段:类型注解 + 可选默认值
    id: int  # 必填字段
    name: str = "未知用户"  # 可选字段(有默认值)
    signup_time: datetime | None = None  # 可选,支持复杂类型
    tags: list[str] = []  # 列表类型,元素为字符串

# 1. 数据校验 & 实例化
# 正确数据:自动校验并转换类型(如 signup_time 字符串转 datetime)
user_data = {
    "id": 123,
    "name": "张三",
    "signup_time": "2024-01-01 12:00:00",
    "tags": ["python", "fastapi"]
}
user = User(** user_data)
print(user.id)  # 123
print(user.signup_time)  # 2024-01-01 12:00:00 (datetime 对象)
print(user.dict())  # 转为字典:{'id': 123, 'name': '张三', ...}

# 2. 错误数据:抛出 ValidationError,提示清晰
invalid_data = {"id": "abc", "name": 123}  # id 应为 int,name 应为 str
try:
    User(** invalid_data)
except ValidationError as e:
    print(e.json())  # 输出 JSON 格式的错误信息,包含字段、错误类型、提示

(2)字段校验规则

Pydantic 提供丰富的校验器,常用的有:

from pydantic import BaseModel, Field, EmailStr, constr

class User(BaseModel):
    # 1. 基础校验:Field 类似 Query/Path,用于模型内字段
    age: int = Field(..., gt=0, lt=150, description="年龄必须在 0-150 之间")
    # 2. 字符串长度限制:constr(constrained string)
    username: constr(min_length=3, max_length=20)  # 用户名 3-20 个字符
    # 3. 特殊类型:EmailStr 校验邮箱格式
    email: EmailStr
    # 4. 可选字段 + 默认值
    is_vip: bool = False

# 正确示例
user = User(
    age=20,
    username="fastapi_learner",
    email="test@example.com"
)
print(user.email)  # test@example.com

# 错误示例(邮箱格式错误)
try:
    User(age=20, username="test", email="invalid-email")
except ValidationError as e:
    print(e)  # 提示:value is not a valid email address

(3)自定义校验器

如果内置校验规则不够用,可通过 @validator 自定义:

from pydantic import BaseModel, validator

class Item(BaseModel):
    name: str
    price: float

    # 自定义校验器:校验 price 必须大于 0
    @validator("price")
    def price_must_be_positive(cls, v):
        if v <= 0:
            raise ValueError("价格必须大于 0")
        return v

    # 多字段校验:校验 name 不能包含敏感词
    @validator("name")
    def name_no_sensitive_words(cls, v):
        sensitive_words = ["非法", "违规"]
        if any(word in v for word in sensitive_words):
            raise ValueError("名称包含敏感词")
        return v

# 错误示例(价格为负)
try:
    Item(name="正常商品", price=-10)
except ValidationError as e:
    print(e)  # 提示:价格必须大于 0

(4)嵌套模型

支持模型嵌套,适合复杂数据结构(如订单包含用户、商品信息):

from pydantic import BaseModel

# 子模型
class Address(BaseModel):
    province: str
    city: str
    detail: str

# 父模型
class Order(BaseModel):
    order_id: str
    user_name: str
    address: Address  # 嵌套 Address 模型
    items: list[Item]  # 列表嵌套 Item 模型

# 实例化
order_data = {
    "order_id": "OD123456",
    "user_name": "李四",
    "address": {
        "province": "广东省",
        "city": "深圳市",
        "detail": "某小区 1 栋"
    },
    "items": [{"name": "手机", "price": 2999}, {"name": "耳机", "price": 199}]
}
order = Order(** order_data)
print(order.address.city)  # 深圳市
print(order.items[0].name)  # 手机

三、FastAPI + Pydantic 结合实战

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field, validator
from typing import List

app = FastAPI(title="商品管理 API", version="1.0")

# 1. 定义 Pydantic 模型(数据校验)
class Item(BaseModel):
    id: int = Field(..., gt=0, description="商品ID")
    name: str = Field(..., min_length=2, max_length=50, description="商品名称")
    price: float = Field(..., gt=0, description="商品价格")
    stock: int = Field(..., ge=0, description="库存数量")

    # 自定义校验:名称不能重复(模拟)
    @validator("name")
    def name_unique(cls, v):
        # 实际项目中可查询数据库校验
        if v in ["测试商品", "默认商品"]:
            raise ValueError("商品名称已存在")
        return v

# 模拟数据库
fake_db: List[Item] = []

# 2. 接口:创建商品(POST)
@app.post("/items/", response_model=Item)  # response_model:指定返回模型(自动过滤多余字段)
def create_item(item: Item):
    # 检查商品ID是否已存在
    for i in fake_db:
        if i.id == item.id:
            raise HTTPException(status_code=400, detail="商品ID已存在")
    fake_db.append(item)
    return item

# 3. 接口:获取所有商品(GET)
@app.get("/items/", response_model=List[Item])
def get_all_items():
    return fake_db

# 4. 接口:获取单个商品(GET)
@app.get("/items/{item_id}", response_model=Item)
def get_item(item_id: int):
    for item in fake_db:
        if item.id == item_id:
            return item
    raise HTTPException(status_code=404, detail="商品不存在")

# 运行:uvicorn main:app --reload
# 访问 http://127.0.0.1:8000/docs 测试接口

总结

  1. FastAPI 核心:以 FastAPI() 实例为入口,通过路径装饰器(@app.get/post)定义接口,结合类型注解实现自动校验和文档生成,核心优势是高性能、自动文档、强类型支持。
  2. Pydantic 核心:基于 BaseModel 定义数据模型,通过内置校验器(Field/EmailStr 等)或自定义校验器(@validator)实现数据校验,是 FastAPI 处理请求体、响应体的底层核心。
  3. 结合使用:FastAPI 接收请求时,通过 Pydantic 模型自动校验数据格式;返回响应时,通过 response_model 指定返回模型,保证数据规范,是 FastAPI 开发的标准范式。

 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐