16 KiB
FastAPI 学习文档
📚 目录
FastAPI 简介
什么是 FastAPI?
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,基于 Python 3.6+ 的类型提示(type hints)。
主要特点
- 高性能:与 NodeJS 和 Go 相当,是最快的 Python 框架之一
- 快速开发:开发速度提升约 200% 到 300%
- 自动文档:自动生成交互式 API 文档(Swagger UI)
- 类型提示:基于 Python 类型提示,提供更好的 IDE 支持
- 异步支持:原生支持 async/await
- 数据验证:自动进行请求和响应数据验证
Flask vs FastAPI 对比
1. 基本语法对比
Flask 写法
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
data = request.get_json()
return jsonify({'msg': 'success'})
FastAPI 写法
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from pydantic import BaseModel
app = FastAPI()
class RequestData(BaseModel):
name: str
age: int
@app.post("/webhook")
async def webhook(data: RequestData):
return JSONResponse({'msg': 'success'})
2. 主要区别
| 特性 | Flask | FastAPI |
|---|---|---|
| 异步支持 | 需要额外库(Flask-AsyncIO) | 原生支持 async/await |
| 类型验证 | 手动验证 | 自动验证(基于 Pydantic) |
| API 文档 | 需要手动编写 | 自动生成(Swagger/OpenAPI) |
| 性能 | 中等 | 高性能(接近 NodeJS) |
| 依赖注入 | 需要额外库 | 内置支持 |
| 数据验证 | 手动处理 | 自动验证和转换 |
3. 请求处理对比
Flask
from flask import request
@app.route('/api', methods=['POST'])
def api():
# 手动获取 JSON 数据
data = request.get_json()
# 手动验证
if not data or 'name' not in data:
return jsonify({'error': '缺少 name 字段'}), 400
return jsonify({'result': data['name']})
FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
age: int
@app.post("/api")
async def api(item: Item):
# 自动验证,如果 name 缺失会自动返回 422 错误
return {'result': item.name}
FastAPI 核心概念
1. 应用实例(FastAPI App)
from fastapi import FastAPI
# 创建 FastAPI 应用实例
app = FastAPI(
title="简道云FastAPI服务", # API 文档标题
description="简道云 API 服务", # API 描述
version="1.0.0" # 版本号
)
项目中的使用(main.py):
app = FastAPI(title="简道云FastAPI服务")
2. 路由装饰器(Route Decorators)
FastAPI 使用装饰器定义路由,类似于 Flask:
@app.get("/") # GET 请求
@app.post("/") # POST 请求
@app.put("/") # PUT 请求
@app.delete("/") # DELETE 请求
项目中的使用(main.py):
@app.post("/webhook")
async def webhook(request: Request):
# 处理逻辑
pass
3. 请求对象(Request)
FastAPI 的 Request 对象提供了访问请求信息的方法:
from fastapi import Request
@app.post("/webhook")
async def webhook(request: Request):
# 获取 JSON 数据
data = await request.json()
# 获取请求头
headers = request.headers
# 获取查询参数
query_params = request.query_params
# 获取路径参数
path_params = request.path_params
项目中的使用(main.py):
@app.post("/webhook")
async def webhook(request: Request):
# 获取请求数据
data = await request.json()
header = request.headers
# 解码请求头
decoded_header = app_tools.decode_headers(header)
4. 响应对象(Response)
FastAPI 提供了多种响应类型:
from fastapi.responses import JSONResponse, HTMLResponse, PlainTextResponse
@app.post("/api")
async def api():
# JSON 响应
return JSONResponse({'msg': 'success'})
# 或者直接返回字典(FastAPI 会自动转换为 JSON)
return {'msg': 'success'}
项目中的使用(main.py):
return JSONResponse(result)
5. 异步函数(Async Functions)
FastAPI 支持异步函数,使用 async 和 await:
@app.post("/webhook")
async def webhook(request: Request):
# 异步获取 JSON 数据
data = await request.json()
# 异步调用其他函数
result = await some_async_function(data)
return result
项目中的使用(main.py):
@app.post("/webhook")
async def webhook(request: Request):
data = await request.json() # 异步获取数据
# ...
result = await anyio.to_thread.run_sync(response_queue.get) # 异步执行同步函数
6. 生命周期事件(Lifecycle Events)
FastAPI 提供了应用启动和关闭事件:
@app.on_event("startup")
async def startup_event():
"""应用启动时执行"""
print("应用启动")
@app.on_event("shutdown")
async def shutdown_event():
"""应用关闭时执行"""
print("应用关闭")
项目中的使用(main.py):
@app.on_event("startup")
def on_startup():
"""应用启动时初始化"""
app.state.app_tools = AppTools(Config)
app.state.logger = setup_global_logger(Config)
app.state.f6_module = F6Module()
app.state.f6_plugin_module = F6PluginModule()
app.state.other_module = OtherPluginModule()
7. 应用状态(Application State)
FastAPI 允许在应用实例上存储状态:
# 设置状态
app.state.my_data = "some value"
# 获取状态
my_data = app.state.my_data
项目中的使用(main.py):
# 在启动时设置
app.state.app_tools = AppTools(Config)
app.state.logger = setup_global_logger(Config)
# 在路由中使用
logger = app.state.logger
app_tools: AppTools = app.state.app_tools
8. 数据验证(Pydantic Models)
FastAPI 使用 Pydantic 进行数据验证:
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
email: str = None # 可选字段
@app.post("/users")
async def create_user(user: User):
# user 已经自动验证和转换
return {"name": user.name, "age": user.age}
项目中的潜在使用(可以改进):
# 可以定义请求模型
class WebhookRequest(BaseModel):
api_key: str
entry_id: str
data_id: str
Action: str = None # 可选字段
@app.post("/webhook")
async def webhook(request: Request, data: WebhookRequest):
# data 已经自动验证
pass
项目中的 FastAPI 使用
1. 项目结构分析
fastapi_app/
├── main.py # FastAPI 应用入口
├── api.py # API 工具类(简道云 API 封装)
├── app/
│ ├── api.py # API 模块(简道云 API 封装)
│ ├── config.py # 配置管理
│ ├── module/ # 业务模块
│ ├── tasks/ # 后台任务
│ └── utils/ # 工具函数
└── requirements.txt # 依赖列表
2. main.py 详解
让我们逐步分析 main.py 文件:
2.1 导入和初始化
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import json
import anyio
from app.utils.app_tools import AppTools, setup_global_logger
from app.module.F6_Plugin_module import F6PluginModule
from app.module.module import F6Module
from app.module.other_module import OtherPluginModule
from app.config import Config
# 创建 FastAPI 应用实例
app = FastAPI(title="简道云FastAPI服务")
说明:
FastAPI:主应用类Request:请求对象,用于访问请求信息JSONResponse:JSON 响应类
2.2 启动事件
@app.on_event("startup")
def on_startup():
"""应用启动时初始化"""
app.state.app_tools = AppTools(Config)
app.state.logger = setup_global_logger(Config)
app.state.f6_module = F6Module()
app.state.f6_plugin_module = F6PluginModule()
app.state.other_module = OtherPluginModule()
说明:
@app.on_event("startup"):应用启动时执行app.state:存储应用级别的状态- 初始化工具类、日志记录器和业务模块
2.3 路由处理
@app.post("/webhook")
async def webhook(request: Request):
"""
接受前端请求后将任务放入消息队列
Returns:
any: 返回任务处理的结果
"""
logger = app.state.logger
app_tools: AppTools = app.state.app_tools
# 获取请求数据
data = await request.json()
header = request.headers
# 解码请求头
decoded_header = app_tools.decode_headers(header)
# 获取操作映射表
action_map = get_action_map()
action = decoded_header.get('Action')
# 处理逻辑...
# 将任务放入消息队列
response_queue = app_tools.enqueue_task(handler, data)
# 等待任务处理结果
result = await anyio.to_thread.run_sync(response_queue.get)
logger.info(json.dumps(result, ensure_ascii=False, indent=4))
return JSONResponse(result)
关键点:
async def:异步函数定义await request.json():异步获取 JSON 数据await anyio.to_thread.run_sync():在线程池中执行同步函数JSONResponse:返回 JSON 响应
3. 任务队列机制
项目使用自定义的任务队列来处理请求:
# 在 app_tools.py 中
class AppTools:
def __init__(self, config):
self.task_queue = Queue()
self._start_task_thread()
def enqueue_task(self, handler, data):
response_queue = Queue()
self.task_queue.put({
'handler': handler,
'data': data,
'response': response_queue
})
return response_queue
工作流程:
- 请求到达
/webhook端点 - 将任务放入队列
- 后台线程处理任务
- 等待结果返回
4. 操作映射机制
项目使用操作映射表来路由不同的操作:
def get_action_map() -> dict:
"""获取操作映射表"""
f6_module = app.state.f6_module
f6_plugin_module = app.state.f6_plugin_module
other_module = app.state.other_module
return {
'login_in': f6_module.accept_login_message,
'get_company_information': f6_module.get_company_information,
'create_brand': f6_plugin_module.create_brand,
# ... 更多操作
}
说明:
- 通过请求头中的
Action字段确定要执行的操作 - 使用字典映射操作名到处理函数
学习路径建议
阶段 1:基础理解(1-2 天)
-
理解 FastAPI 基本概念
- 阅读官方文档:https://fastapi.tiangolo.com/
- 理解路由、请求、响应的基本用法
-
运行项目
# 安装依赖 pip install -r requirements.txt # 运行项目 python main.py # 或 uvicorn main:app --reload -
访问 API 文档
- 启动后访问:http://localhost:5003/docs
- 查看自动生成的 Swagger UI 文档
阶段 2:代码分析(2-3 天)
-
分析 main.py
- 理解应用初始化流程
- 理解路由处理逻辑
- 理解任务队列机制
-
分析业务模块
- 查看
app/module/目录下的模块 - 理解操作映射机制
- 理解模块间的交互
- 查看
-
分析工具类
- 查看
app/utils/app_tools.py - 理解任务队列实现
- 理解日志记录机制
- 查看
阶段 3:实践练习(3-5 天)
-
添加新路由
@app.get("/health") async def health_check(): return {"status": "ok"} -
添加数据验证
from pydantic import BaseModel class WebhookData(BaseModel): api_key: str entry_id: str data_id: str @app.post("/webhook") async def webhook(data: WebhookData): return {"received": data.dict()} -
添加错误处理
from fastapi import HTTPException @app.post("/webhook") async def webhook(request: Request): try: data = await request.json() # 处理逻辑 except Exception as e: raise HTTPException(status_code=500, detail=str(e))
阶段 4:深入学习(1-2 周)
-
学习异步编程
- 理解
async/await - 理解
asyncio - 理解并发处理
- 理解
-
学习 Pydantic
- 数据验证
- 数据序列化
- 自定义验证器
-
学习依赖注入
- FastAPI 的依赖注入系统
- 数据库连接管理
- 认证和授权
常见问题解答
Q1: FastAPI 和 Flask 的主要区别是什么?
A: 主要区别:
- 性能:FastAPI 性能更高,支持异步
- 类型验证:FastAPI 自动验证,Flask 需要手动
- API 文档:FastAPI 自动生成,Flask 需要手动编写
- 异步支持:FastAPI 原生支持,Flask 需要额外库
Q2: 为什么使用 async def 而不是 def?
A:
async def允许使用await关键字- 可以异步处理 I/O 操作(如网络请求、数据库查询)
- 提高并发性能
示例:
# 同步(阻塞)
def sync_function():
data = requests.get("https://api.example.com") # 阻塞
return data
# 异步(非阻塞)
async def async_function():
async with httpx.AsyncClient() as client:
data = await client.get("https://api.example.com") # 非阻塞
return data
Q3: app.state 是什么?为什么要用它?
A:
app.state是 FastAPI 提供的应用级状态存储- 用于存储需要在多个路由之间共享的数据
- 类似于 Flask 的
g对象,但作用域是整个应用
项目中的使用:
# 启动时设置
app.state.logger = setup_global_logger(Config)
# 在路由中使用
logger = app.state.logger
Q4: 如何处理同步函数?
A:
使用 anyio.to_thread.run_sync() 在线程池中执行同步函数:
import anyio
# 同步函数
def sync_function(data):
# 耗时操作
return result
# 在异步函数中调用
@app.post("/api")
async def api(request: Request):
result = await anyio.to_thread.run_sync(sync_function, data)
return result
Q5: 如何添加中间件?
A:
使用 @app.middleware() 装饰器:
@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
Q6: 如何添加 CORS 支持?
A:
使用 CORSMiddleware:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 允许所有源
allow_credentials=True,
allow_methods=["*"], # 允许所有方法
allow_headers=["*"], # 允许所有头
)
Q7: 如何添加认证?
A: 使用依赖注入:
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer
security = HTTPBearer()
async def verify_token(token: str = Depends(security)):
if token != "valid_token":
raise HTTPException(status_code=401, detail="Invalid token")
return token
@app.post("/api")
async def api(token: str = Depends(verify_token)):
return {"message": "Authenticated"}
推荐资源
- 官方文档:https://fastapi.tiangolo.com/
- 中文文档:https://fastapi.tiangolo.com/zh/
- Pydantic 文档:https://docs.pydantic.dev/
- Uvicorn 文档:https://www.uvicorn.org/
总结
FastAPI 是一个现代、高性能的 Web 框架,特别适合构建 API。相比 Flask,它提供了:
- 更好的性能:异步支持,高性能
- 自动验证:基于类型提示的自动数据验证
- 自动文档:自动生成 API 文档
- 更好的开发体验:类型提示、IDE 支持
通过这个项目,你可以学习到:
- FastAPI 的基本用法
- 异步编程
- 任务队列机制
- 模块化架构设计
建议按照学习路径逐步深入,多实践、多思考,逐步掌握 FastAPI 的精髓。