一. FastAPI 简介
1.1 什么是 FastAPI
FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Web 框架,专为在 Python 中构建 RESTful API 而设计。它使用 Python 3.8 + 并基于标准的 Python 类型提示,建立在 Starlette 和 Pydantic 之上
技术栈基础:
- Starlette:轻量级 ASGI 框架,提供异步支持
- Pydantic:数据验证和设置管理库
- OpenAPI:API 文档标准
- Python 类型提示:代码提示和验证
1.2 FastAPI 的核心特点
🚀 卓越性能
- 基于异步编程模型,性能接近 Node.js 和 Go
- 支持并发请求处理
- 低延迟和高吞吐量
📝 自动文档生成
- 自动生成交互式 API 文档
- 支持 Swagger UI 和 ReDoc 两种风格
- 基于 OpenAPI 3.0 规范
🎯 强大的类型支持
- 利用 Python 3.8 + 的类型提示
- 编译时类型检查
- 优秀的 IDE 支持和代码提示
🔧 易于使用
- 直观的 API 设计
- 最少的样板代码
- 快速的开发周期
1.3 适用场景
- 前后端分离项目:作为 API 后端服务
- 微服务架构:独立的服务组件
- 数据 API:处理和返回 JSON 数据
- 实时应用:支持 WebSocket 协议
- 自动化测试:快速构建测试接口
1.4 为什么选择 FastAPI
与其他框架对比:
|------|---------|--------|--------|
| 特性 | FastAPI | Flask | Django |
| 性能 | 极高(异步) | 中等(同步) | 中等(同步) |
| 文档 | 自动生成 | 需要扩展 | 需要扩展 |
| 类型支持 | 原生支持 | 有限支持 | 有限支持 |
| 学习曲线 | 平缓 | 平缓 | 陡峭 |
| 生态系统 | 快速增长 | 非常成熟 | 非常成熟 |
二. 环境搭建与安装
2.1 系统要求
- Python 版本:3.8 或更高版本
- 操作系统:Windows、macOS、Linux 均可
- 内存:建议至少 1GB(生产环境更多)
2.2 安装方法
(1)使用 pip 安装(推荐)
bash
# 基础安装
pip install fastapi
# 安装ASGI服务器(生产环境必需)
pip install uvicorn
# 或者安装所有依赖(包含开发工具)
pip install fastapi[all]
(2)使用 conda 安装
bash
conda install -c conda-forge fastapi uvicorn
(3) 验证安装
bash
# 检查FastAPI版本
python -c "import fastapi; print(f'FastAPI版本: {fastapi.__version__}')"
# 检查uvicorn版本
python -c "import uvicorn; print(f'Uvicorn版本: {uvicorn.__version__}')"
2.3 开发环境配置
(1) IDE 推荐
- PyCharm:完整的 Python 开发环境
- VS Code:轻量级,丰富的 Python 插件
- Jupyter Notebook:交互式开发
(2) 项目结构
bash
my_fastapi_project/
├── main.py # 应用入口文件
├── requirements.txt # 依赖列表
├── .gitignore # Git忽略文件
└── README.md # 项目说明
三. 第一个 FastAPI 应用
3.1 创建基础应用
创建一个名为 main.py 的文件:
python
# main.py
from typing import Union
from fastapi import FastAPI
# 创建FastAPI实例
app = FastAPI(
title="我的第一个FastAPI应用",
description="这是一个简单的FastAPI示例",
version="1.0.0",
)
# 定义根路径的GET请求
@app.get("/")
def read_root():
"""
根路径接口
- 描述:返回欢迎信息
- 方法:GET
- 返回:JSON格式的欢迎信息
"""
return {"message": "欢迎使用FastAPI!", "version": "1.0.0"}
# 定义带参数的GET请求
@app.get("/items/{item_id}")
def read_item(
item_id: int,
q: Union[str, None] = None,
price: float = 0.0
):
"""
获取商品信息
- 描述:根据商品ID获取商品信息
- 参数:
- item_id: 商品ID(路径参数)
- q: 查询关键词(查询参数,可选)
- price: 价格筛选(查询参数,默认0.0)
- 返回:包含商品信息的JSON
"""
result = {"item_id": item_id}
if q:
result["query"] = q
if price > 0:
result["price"] = price
return result
3.2 启动应用
(1) 开发模式启动
bash
# 基础启动
uvicorn main:app --reload
# 指定主机和端口
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
# 详细日志模式
uvicorn main:app --reload --log-level debug
参数说明:
- --reload:开发模式,代码修改后自动重启
- --host 0.0.0.0:允许外部访问
- --port 8000:指定端口号
(2)访问应用
3.3 代码解析
(1)核心概念
python
# 导入FastAPI类
from fastapi import FastAPI
# 创建应用实例
app = FastAPI()
# 路由装饰器
@app.get("/")
def read_root():
return {"Hello": "World"}
(2)路由装饰器
FastAPI 使用装饰器来定义路由:
python
# GET请求
@app.get("/path")
def get_handler():
pass
# POST请求
@app.post("/path")
def post_handler():
pass
# PUT请求
@app.put("/path")
def put_handler():
pass
# DELETE请求
@app.delete("/path")
def delete_handler():
pass
4. 路由与参数详解
4.1 HTTP 方法详解
FastAPI 支持所有标准 HTTP 方法:
python
from fastapi import FastAPI
app = FastAPI()
# GET - 获取资源
@app.get("/users")
def get_users():
"""获取所有用户"""
return {"method": "GET", "action": "获取用户列表"}
# POST - 创建资源
@app.post("/users")
def create_user(user_data: dict):
"""创建新用户"""
return {"method": "POST", "action": "创建用户", "data": user_data}
# PUT - 完整更新资源
@app.put("/users/{user_id}")
def update_user(user_id: int, user_data: dict):
"""更新用户信息(完整更新)"""
return {"method": "PUT", "action": "更新用户", "user_id": user_id, "data": user_data}
# PATCH - 部分更新资源
@app.patch("/users/{user_id}")
def partial_update_user(user_id: int, user_data: dict):
"""部分更新用户信息"""
return {"method": "PATCH", "action": "部分更新用户", "user_id": user_id, "data": user_data}
# DELETE - 删除资源
@app.delete("/users/{user_id}")
def delete_user(user_id: int):
"""删除用户"""
return {"method": "DELETE", "action": "删除用户", "user_id": user_id}
4.2 参数类型详解
(1) 路径参数(Path Parameters)
路径参数是 URL 路径的一部分:
python
from fastapi import FastAPI, HTTPException
app = FastAPI()
# 基础路径参数
@app.get("/users/{user_id}")
def get_user(user_id: int):
"""根据ID获取用户"""
return {"user_id": user_id}
# 多个路径参数
@app.get("/users/{user_id}/items/{item_id}")
def get_user_item(user_id: int, item_id: str):
"""获取用户的特定商品"""
return {"user_id": user_id, "item_id": item_id}
# 路径参数验证
@app.get("/items/{item_id}")
def get_item(
item_id: int = Path(..., title="商品ID", description="商品的唯一标识符", ge=1, le=1000)
):
"""带验证的路径参数"""
if item_id not in range(1, 1001):
raise HTTPException(status_code=404, detail="商品不存在")
return {"item_id": item_id}
(2)查询参数(Query Parameters)
查询参数是 URL 中?后面的键值对:
python
from fastapi import FastAPI, Query
from typing import Union, List
app = FastAPI()
# 基础查询参数
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 10):
"""分页获取商品列表"""
return {"skip": skip, "limit": limit}
# 可选查询参数
@app.get("/search/")
def search(q: Union[str, None] = None):
"""搜索功能"""
if q:
return {"query": q, "results": ["结果1", "结果2"]}
return {"message": "请提供搜索关键词"}
# 查询参数验证
@app.get("/filter/")
def filter_items(
min_price: float = Query(0, ge=0, description="最低价格"),
max_price: float = Query(1000, le=1000, description="最高价格"),
categories: Union[List[str], None] = Query(None, description="商品分类")
):
"""带过滤条件的查询"""
return {
"min_price": min_price,
"max_price": max_price,
"categories": categories
}
(3)请求体参数(Request Body)
请求体是客户端发送给服务器的数据:
python
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Union
app = FastAPI()
# 定义数据模型
class Item(BaseModel):
name: str
price: float
is_offer: Union[bool, None] = None
# 使用请求体
@app.post("/items/")
def create_item(item: Item):
"""创建商品"""
item_dict = item.dict()
if item.is_offer:
item_dict.update({"discount": 0.1})
return item_dict
# 混合参数类型
@app.put("/items/{item_id}")
def update_item(
item_id: int,
item: Item,
q: Union[str, None] = None
):
"""更新商品(混合参数)"""
result = {"item_id": item_id, **item.dict()}
if q:
result["query"] = q
return result
4.3 参数验证与约束
FastAPI 提供强大的参数验证功能:
python
from fastapi import FastAPI, Path, Query, Body
from typing import Union, List
from pydantic import BaseModel, Field
app = FastAPI()
# 路径参数验证
@app.get("/items/{item_id}")
def read_item(
item_id: int = Path(
...,
title="商品ID",
description="商品的唯一标识符",
ge=1, # 大于等于1
le=1000, # 小于等于1000
example=42 # 示例值
),
q: Union[str, None] = Query(
None,
title="查询关键词",
description="用于搜索商品的关键词",
min_length=3, # 最小长度3
max_length=50, # 最大长度50
regex="^[a-zA-Z0-9 ]*$" # 正则表达式验证
)
):
return {"item_id": item_id, "q": q}
# 请求体验证
class User(BaseModel):
username: str = Field(
...,
title="用户名",
description="用户的登录名",
min_length=3,
max_length=20,
example="johndoe"
)
email: str = Field(
...,
title="邮箱",
description="用户的邮箱地址",
regex=r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
example="john@example.com"
)
age: int = Field(
None,
title="年龄",
description="用户年龄",
ge=18,
le=120
)
@app.post("/users/")
def create_user(user: User = Body(..., description="用户信息")):
return user
5. 交互式 API 文档
5.1 自动生成的文档
FastAPI 自动生成两种交互式 API 文档:
(1) Swagger UI(推荐)
访问地址:http://127.0.0.1:8000/docs
功能特点:
- 交互式界面,支持直接测试 API
- 自动生成请求参数表单
- 显示响应示例和状态码
- 支持认证和授权
- 可导出 API 文档
(2)ReDoc
访问地址:http://127.0.0.1:8000/redoc
功能特点:
- 更简洁的文档风格
- 更好的排版和可读性
- 支持 Markdown 格式的描述
- 适合生产环境展示
5.2 文档配置与定制
(1)应用元数据配置
python
from fastapi import FastAPI
app = FastAPI(
title="电子商务API",
description="""
这是一个完整的电子商务API服务,提供以下功能:
- 用户管理:注册、登录、个人信息管理
- 商品管理:商品CRUD、分类、搜索
- 订单管理:创建订单、支付、物流跟踪
- 购物车:添加商品、修改数量、结算
**技术栈:** FastAPI + Pydantic + SQLAlchemy
""",
version="2.0.0",
terms_of_service="http://example.com/terms/",
contact={
"name": "API支持团队",
"url": "http://example.com/contact/",
"email": "support@example.com",
},
license_info={
"name": "MIT License",
"url": "https://opensource.org/licenses/MIT",
},
)
@app.get("/")
def read_root():
return {"message": "欢迎使用电子商务API"}
(2)接口文档配置
python
from fastapi import FastAPI, Query
from typing import Union
app = FastAPI()
@app.get(
"/items/",
summary="获取商品列表",
description="""
获取商品列表,支持分页和过滤:
- **分页**:通过skip和limit参数控制
- **过滤**:通过category和min_price参数过滤
- **排序**:通过sort_by参数指定排序字段
返回商品的基本信息,包括ID、名称、价格等。
""",
response_description="成功返回商品列表",
tags=["商品管理"],
deprecated=False # 是否弃用
)
def read_items(
skip: int = Query(0, description="跳过的商品数量", ge=0),
limit: int = Query(10, description="获取的商品数量", ge=1, le=100),
category: Union[str, None] = Query(None, description="商品分类"),
min_price: Union[float, None] = Query(None, description="最低价格", ge=0)
):
"""
获取商品列表:
- **skip**: 跳过的商品数量(默认0)
- **limit**: 获取的商品数量(默认10,最大100)
- **category**: 商品分类(可选)
- **min_price**: 最低价格(可选)
返回包含商品信息的列表。
"""
return {"skip": skip, "limit": limit, "category": category, "min_price": min_price}
5.3 文档分组与标签
使用tags参数对 API 进行分组:
python
from fastapi import FastAPI
app = FastAPI()
# 用户管理相关接口
@app.get("/users/", tags=["用户管理"], summary="获取用户列表")
def get_users():
"""获取所有用户的基本信息"""
return {"message": "用户列表"}
@app.post("/users/", tags=["用户管理"], summary="创建新用户")
def create_user(user_data: dict):
"""创建新用户,需要提供用户名、邮箱和密码"""
return {"message": "用户创建成功", "data": user_data}
@app.get("/users/{user_id}", tags=["用户管理"], summary="获取用户详情")
def get_user(user_id: int):
"""根据用户ID获取用户的详细信息"""
return {"user_id": user_id, "message": "用户详情"}
# 商品管理相关接口
@app.get("/items/", tags=["商品管理"], summary="获取商品列表")
def get_items():
"""获取所有商品的基本信息"""
return {"message": "商品列表"}
@app.post("/items/", tags=["商品管理"], summary="创建新商品")
def create_item(item_data: dict):
"""创建新商品,需要提供商品名称、价格、描述等信息"""
return {"message": "商品创建成功", "data": item_data}
# 订单管理相关接口
@app.get("/orders/", tags=["订单管理"], summary="获取订单列表")
def get_orders():
"""获取所有订单的基本信息"""
return {"message": "订单列表"}
@app.post("/orders/", tags=["订单管理"], summary="创建新订单")
def create_order(order_data: dict):
"""创建新订单,需要提供商品ID、数量、收货地址等信息"""
return {"message": "订单创建成功", "data": order_data}
5.4 响应模型文档
python
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List, Union
app = FastAPI()
# 定义响应模型
class Item(BaseModel):
"""商品信息模型"""
id: int
name: str
price: float
description: Union[str, None] = None
class ItemListResponse(BaseModel):
"""商品列表响应模型"""
items: List[Item]
total: int
skip: int
limit: int
@app.get("/items/", response_model=ItemListResponse, summary="获取商品列表")
def read_items(skip: int = 0, limit: int = 10):
"""
获取商品列表:
- 返回商品的详细信息
- 包含分页信息
- 支持大量数据的高效返回
"""
# 模拟数据库查询
mock_items = [
{"id": 1, "name": "商品1", "price": 99.99, "description": "这是商品1的描述"},
{"id": 2, "name": "商品2", "price": 199.99},
]
return {
"items": mock_items,
"total": len(mock_items),
"skip": skip,
"limit": limit
}
FastAPI 的学习是一个循序渐进的过程,建议你在实际项目中不断实践和探索。在下一篇文章中,我们将深入学习 FastAPI 的进阶特性和实战应用