一、FastAPI框架基础入门
1.1 什么是FastAPI
FastAPI是基于Python 3.6+类型提示构建的现代Web框架,其核心特性包括:
高性能:通过Starlette实现异步处理,性能媲美Node.js和Go智能编辑器支持:自动补全和类型检查显著提升开发效率自动生成文档:内置Swagger UI和ReDoc交互式文档数据验证:基于Pydantic库的自动数据校验标准化:兼容OpenAPI和JSON Schema规范
1.2 环境搭建与第一个API
# 创建虚拟环境(确保Python 3.6+已安装)
python -m venv venv
source venv/bin/activate # Linux/Mac
# 或
venvScriptsactivate # Windows
# 安装FastAPI和ASGI服务器(uvicorn是ASGI服务器,用于运行FastAPI应用)
pip install fastapi uvicorn
# main.py - 首个FastAPI应用
from fastapi import FastAPI # 导入FastAPI类
# 创建FastAPI应用实例
app = FastAPI()
# 定义根路径的GET请求处理函数
@app.get("/") # 使用装饰器定义路由
def read_root():
"""返回一个JSON响应,表示应用已启动"""
return {"message": "Hello, FastAPI!"} # 响应内容
# 仅当直接运行此脚本时启动服务器
if __name__ == "__main__":
import uvicorn # 导入uvicorn服务器
# 启动应用:监听0.0.0.0:8000,启用自动重载(开发环境使用)
uvicorn.run(app, host="0.0.0.0", port=8000)
运行与验证:
在终端运行 访问
uvicorn main:app --reload 查看自动生成的交互式API文档文档会显示
http://localhost:8000/docs 接口的测试界面,点击”Try it out”可直接测试
GET /
二、API端点与路由系统
2.1 路由定义方式
from fastapi import FastAPI
app = FastAPI()
# 路径参数:{item_id} 会被视为路径变量
@app.get("/items/{item_id}")
def read_item(item_id: int):
"""
获取指定ID的商品信息
参数:
item_id: 路径参数,必须是整数
返回:
包含商品ID的字典
"""
return {"item_id": item_id}
# POST请求示例:创建新商品
@app.post("/items/")
def create_item(item: dict):
"""
创建新商品
参数:
item: 请求体中的JSON数据(字典)
返回:
包含"created"键的字典
"""
return {"created": item}
关键点说明:
/
@app.get() 装饰器定义HTTP方法
@app.post() 是路径参数,FastAPI会自动将其转换为
{item_id}变量参数类型注解(如
item_id)触发数据验证无需手动解析请求数据,FastAPI自动处理
item_id: int
2.2 路由组织最佳实践
from fastapi import APIRouter, FastAPI
# 创建路由组
router = APIRouter(
prefix="/users", # 路由前缀
tags=["User APIs"] # 文档标签
)
# 用户列表路由
@router.get("/")
def list_users():
"""返回用户列表"""
return ["user1", "user2"]
# 获取单个用户路由
@router.get("/{user_id}")
def get_user(user_id: int):
"""获取指定ID的用户信息"""
return {"user_id": user_id}
# 主应用实例
app = FastAPI()
# 将路由组包含到主应用
app.include_router(router)
优势解析:
实现路由模块化,便于大型项目维护
APIRouter 自动添加到所有子路由路径(如
prefix)
/users/ 用于在文档中组织API分组保持主应用文件简洁,业务逻辑分散到不同模块
tags
三、参数处理详解
3.1 路径参数(Path Parameters)
from fastapi import Path # 导入Path类型
@app.get("/items/{item_id}")
def read_item(
item_id: int = Path(..., # ... 表示必填参数
title="Item ID", # 文档标题
description="ID of the item to get", # 描述
ge=1, # 最小值(greater than or equal to 1)
le=100), # 最大值(less than or equal to 100)
q: str = Path(None, max_length=50) # 可选参数,最大长度50
):
"""
获取商品详情,带路径参数验证
参数:
item_id: 必填整数,1-100范围
q: 可选字符串,最大长度50
返回:
包含商品ID和查询参数的字典
"""
return {"item_id": item_id, "q": q}
验证规则说明:
:要求参数值 ≥ 1(最小值)
ge=1:要求参数值 ≤ 100(最大值)
le=100:限制字符串最大长度
max_length=50 表示可选参数(默认值为None)
None 表示必填参数(无默认值)
...
测试示例:
有效请求: → 返回
/items/5?q=search无效请求:
{"item_id":5, "q":"search"} → 返回422错误(参数验证失败)
/items/0?q=test
3.2 查询参数(Query Parameters)
from fastapi import Query # 导入Query类型
@app.get("/search")
def search_items(
q: str = Query(..., # 必填参数
min_length=3, # 最小长度3
max_length=50, # 最大长度50
description="Search term"), # 参数描述
skip: int = Query(0, ge=0), # 默认值0,最小值0
limit: int = Query(10, le=100) # 默认值10,最大值100
):
"""
搜索功能,支持分页和查询词
参数:
q: 必填字符串,长度3-50
skip: 可选整数,分页偏移量(默认0)
limit: 可选整数,分页大小(默认10,最大100)
返回:
包含搜索参数的字典
"""
return {"q": q, "skip": skip, "limit": limit}
关键特性:
:标记必填参数
Query(...)/
min_length:字符串长度限制
max_length/
ge:数值范围限制默认值:
le 表示参数可选,有默认值文档自动生成:在Swagger UI中会显示参数描述和限制
skip=0
请求示例:
GET /search?q=fastapi&skip=10&limit=20
返回:
{"q": "fastapi", "skip": 10, "limit": 20}
3.3 请求体(Body Parameters)
from pydantic import BaseModel # 导入Pydantic模型
from fastapi import Body # 导入Body类型
# 定义请求体模型
class Item(BaseModel):
name: str # 必填字符串
price: float # 必填浮点数
is_offer: bool = None # 可选布尔值(默认None)
@app.put("/items/{item_id}")
def update_item(
item_id: int,
item: Item = Body(..., # 必填请求体
embed=True) # 嵌套结构处理
):
"""
更新商品信息
参数:
item_id: 路径参数
item: 请求体(JSON格式),需符合Item模型
返回:
包含商品ID和更新内容的字典
"""
return {"item_id": item_id, "item": item}
嵌套结构说明:
:当请求体是JSON对象时,FastAPI会将其嵌套在顶层
embed=True
无embed:有embed:
{"name": "Foo", "price": 42}
{"item": {"name": "Foo", "price": 42}}
Pydantic自动验证请求体:
字段类型检查(name必须是字符串)必填字段验证(price必须提供)自动返回422错误(验证失败)
请求示例(使用curl):
curl -X PUT "http://localhost:8000/items/42"
-H "Content-Type: application/json"
-d '{"name": "Foo", "price": 42}'
3.4 表单数据与文件处理
from fastapi import File, UploadFile, Form # 导入文件处理类型
@app.post("/upload")
def upload_file(
file: UploadFile = File(...), # 必填文件
description: str = Form(...) # 必填表单字段
):
"""
处理文件上传和表单数据
参数:
file: 上传的文件(必填)
description: 表单描述(必填)
返回:
包含文件信息的字典
"""
return {
"filename": file.filename, # 文件原始名称
"description": description, # 表单描述
"content_type": file.content_type # 文件MIME类型
}
关键点解析:
:指定为文件上传字段(必填)
File(...):获取表单字段(必填)
Form(...) 对象包含:
UploadFile
:客户端原始文件名
filename:MIME类型(如
content_type)
image/jpeg:文件对象(可读取内容)
file
请求格式:必须使用(浏览器表单提交)
multipart/form-data
curl测试示例:
curl -X POST "http://localhost:8000/upload"
-F "file=@/path/to/file.txt"
-F "description=Sample file"
四、Header与Cookie参数处理
4.1 请求头(Header)参数
from fastapi import Header # 导入Header类型
@app.get("/headers")
def get_headers(
user_agent: str = Header(..., # 必填请求头
convert_underscores=False), # 保持下划线原样
x_token: list[str] = Header(None) # 可选列表(支持重复头)
):
"""
获取请求头信息
参数:
user_agent: 必填请求头(保持下划线原样)
x_token: 可选请求头(支持多个值)
返回:
包含请求头信息的字典
"""
return {
"user_agent": user_agent, # User-Agent值
"x_token": x_token # X-Token值(列表形式)
}
特殊参数说明:
:默认情况下FastAPI会将
convert_underscores=False转换为
user_agent,此参数保持原样
User-Agent:允许接收多个相同名称的头(如
list[str] 和
X-Token: a)标准请求头(如
X-Token: b)会自动包含在请求中
User-Agent
请求示例:
GET /headers HTTP/1.1
User-Agent: FastAPI-Client
X-Token: token1
X-Token: token2
4.2 Cookie参数管理
from fastapi import Cookie, Depends # 导入Cookie和依赖注入
@app.get("/cookies")
def get_cookies(
ads_id: str = Cookie(None), # 可选Cookie
session_id: str = Cookie(...) # 必填Cookie
):
"""
获取Cookie值
参数:
ads_id: 可选Cookie(默认None)
session_id: 必填Cookie
返回:
包含Cookie值的字典
"""
return {"ads_id": ads_id, "session_id": session_id}
# 使用Pydantic模型管理多个Cookie
from pydantic import BaseModel
class UserCookies(BaseModel):
session_id: str # 必填
tracking_id: str = None # 可选
@app.get("/user-cookies")
def get_user_cookies(cookies: UserCookies = Depends()):
"""
通过依赖注入获取Cookie
参数:
cookies: UserCookies模型(自动从Cookie解析)
返回:
解析后的Cookie对象
"""
return cookies
Cookie处理解析:
:标记为必填Cookie
Cookie(...):标记为可选Cookie(默认None)
Cookie(None):依赖注入机制,自动从Cookie解析Pydantic模型验证Cookie结构:
Depends()
必须存在
session_id 可选
tracking_id
设置Cookie示例(在响应中):
from fastapi import Response
@app.post("/login")
def login(response: Response):
response.set_cookie(key="session_id", value="abc123")
return {"message": "Login successful"}
五、完整示例解析
5.1 综合API实现
from fastapi import FastAPI, Path, Query, Body, File, UploadFile, Header, Cookie, Depends
from pydantic import BaseModel
from typing import Optional, List
app = FastAPI()
# 定义商品模型
class Item(BaseModel):
name: str
description: Optional[str] = None # 可选字段
price: float
tax: Optional[float] = None # 可选字段
@app.post("/items/{item_id}", status_code=201)
def create_item(
item_id: int = Path(..., # 必填路径参数
title="Item ID",
ge=1,
description="ID of the item to create"),
item: Item = Body(..., # 必填请求体
embed=True),
user_agent: str = Header(default=None), # 请求头(可选)
x_token: List[str] = Header(default=None), # 多值请求头
file: UploadFile = File(...), # 必填文件
session_id: str = Cookie(...) # 必填Cookie
):
"""
创建新商品的综合API
参数:
item_id: 商品ID(1-100)
item: 商品数据(JSON请求体)
user_agent: User-Agent请求头
x_token: X-Token请求头(支持多个值)
file: 上传的文件
session_id: 会话Cookie
返回:
包含所有参数的响应
"""
return {
"item_id": item_id,
"item": item,
"user_agent": user_agent,
"x_token": x_token,
"filename": file.filename,
"session_id": session_id
}
5.2 测试用例(详细说明)
# 使用curl测试完整API
curl -X POST "http://localhost:8000/items/42"
-H "Content-Type: application/json"
-H "Authorization: Bearer my_token"
-H "X-Token: first"
-H "X-Token: second"
-H "User-Agent: FastAPI-Test"
-F 'file=@/path/to/test.txt'
-F 'item={"name": "FastAPI", "price": 42.0}'
-b "session_id=abc123"
参数解析:
| 参数 | 类型 | 说明 | 示例值 |
|---|---|---|---|
|
路径参数 | 商品ID | |
|
请求体 | 商品数据 | |
|
Header | 认证头 | |
|
Header | 多值头 | 和 |
|
Header | 浏览器标识 | |
|
文件 | 上传文件 | |
|
Cookie | 会话ID | |
响应示例:
{
"item_id": 42,
"item": {
"name": "FastAPI",
"description": null,
"price": 42.0,
"tax": null
},
"user_agent": "FastAPI-Test",
"x_token": [
"first",
"second"
],
"filename": "test.txt",
"session_id": "abc123"
}
六、最佳实践总结
6.1 参数验证原则
必填参数:使用 (不提供默认值)范围限制:
= .../
ge(数值),
le/
min_length(字符串)类型安全:通过类型注解自动验证文档友好:添加
max_length/
title 提升文档可读性
description
6.2 路由组织规范
使用 分割功能模块为每个路由组添加
APIRouter 和
prefix保持单一职责:每个路由处理一个明确功能
tags
6.3 文件与表单处理
优先使用 和
File 类型避免手动处理
Form 数据限制文件大小(通过
multipart 和
max_files 参数)
max_size
6.4 安全建议
路径参数:始终使用 /
ge 避免无效ID查询参数:限制长度和范围防止注入Cookie:使用
le 和
secure 标志(在生产环境)敏感数据:避免在URL中传递敏感信息(使用请求体或Cookie)
http_only
七、性能优化建议
7.1 异步处理
from fastapi import FastAPI
import httpx # 异步HTTP客户端
app = FastAPI()
@app.get("/async")
async def async_endpoint():
"""异步示例:使用async/await处理IO操作"""
async with httpx.AsyncClient() as client: # 异步客户端
response = await client.get("https://example.com") # 等待网络请求
return {"content": response.text} # 返回响应内容
优势:
非阻塞I/O操作(网络/数据库)提升并发处理能力适用于高延迟操作
7.2 缓存策略
from fastapi_cache import FastAPICache
from fastapi_cache.backends.redis import RedisBackend
import redis
app = FastAPI()
# 启动时初始化缓存
@app.on_event("startup")
async def startup():
redis_client = redis.Redis(host="localhost", port=6379, db=0)
FastAPICache.init(RedisBackend(redis_client), prefix="fastapi-cache")
@app.get("/cached")
def cached_endpoint():
"""带缓存的API,缓存5分钟"""
return {"message": "This response is cached"}
配置说明:
使用Redis作为缓存后端 用于区分不同应用的缓存默认缓存时间:5分钟(可配置)自动处理缓存命中/未命中
prefix
结论
FastAPI通过类型提示和自动验证,将API开发提升到新高度。本教程详细解析了:
路径参数:使用实现路径变量验证查询参数:通过
Path添加长度/范围限制请求体:结合Pydantic模型实现结构化数据验证表单与文件:
Query和
File简化文件上传处理Header/Cookie:安全获取请求元数据
Form
关键优势总结:
✅ 开发效率:类型提示+自动文档✅ 数据安全:自动验证避免脏数据✅ 性能:异步支持+缓存集成✅ 可维护性:模块化路由+清晰参数定义
通过掌握这些核心参数处理技术,您已具备构建健壮、安全、高性能API的基础能力。在实际项目中,建议:
为所有参数添加描述()为必填参数使用
description(不提供默认值)为数值参数添加范围限制(
.../
ge)使用
le组织大型应用
APIRouter
最后提醒:FastAPI的文档是最佳学习资源,始终通过访问
验证您的API设计。随着您对参数处理的深入,将能构建出既符合REST规范又高度安全的生产级API。
/docs















暂无评论内容