简道云fastapi

This commit is contained in:
z66
2025-11-07 17:48:49 +08:00
commit 073f0646a1
30 changed files with 5933 additions and 0 deletions
+710
View File
@@ -0,0 +1,710 @@
# FastAPI 学习文档
## 📚 目录
1. [FastAPI 简介](#fastapi-简介)
2. [Flask vs FastAPI 对比](#flask-vs-fastapi-对比)
3. [FastAPI 核心概念](#fastapi-核心概念)
4. [项目中的 FastAPI 使用](#项目中的-fastapi-使用)
5. [学习路径建议](#学习路径建议)
6. [常见问题解答](#常见问题解答)
---
## FastAPI 简介
### 什么是 FastAPI
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,基于 Python 3.6+ 的类型提示(type hints)。
### 主要特点
1. **高性能**:与 NodeJS 和 Go 相当,是最快的 Python 框架之一
2. **快速开发**:开发速度提升约 200% 到 300%
3. **自动文档**:自动生成交互式 API 文档(Swagger UI
4. **类型提示**:基于 Python 类型提示,提供更好的 IDE 支持
5. **异步支持**:原生支持 async/await
6. **数据验证**:自动进行请求和响应数据验证
---
## Flask vs FastAPI 对比
### 1. 基本语法对比
#### Flask 写法
```python
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 写法
```python
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
```python
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
```python
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
```python
from fastapi import FastAPI
# 创建 FastAPI 应用实例
app = FastAPI(
title="简道云FastAPI服务", # API 文档标题
description="简道云 API 服务", # API 描述
version="1.0.0" # 版本号
)
```
**项目中的使用**`main.py`):
```python
app = FastAPI(title="简道云FastAPI服务")
```
### 2. 路由装饰器(Route Decorators
FastAPI 使用装饰器定义路由,类似于 Flask:
```python
@app.get("/") # GET 请求
@app.post("/") # POST 请求
@app.put("/") # PUT 请求
@app.delete("/") # DELETE 请求
```
**项目中的使用**`main.py`):
```python
@app.post("/webhook")
async def webhook(request: Request):
# 处理逻辑
pass
```
### 3. 请求对象(Request
FastAPI 的 `Request` 对象提供了访问请求信息的方法:
```python
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`):
```python
@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 提供了多种响应类型:
```python
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`):
```python
return JSONResponse(result)
```
### 5. 异步函数(Async Functions
FastAPI 支持异步函数,使用 `async``await`
```python
@app.post("/webhook")
async def webhook(request: Request):
# 异步获取 JSON 数据
data = await request.json()
# 异步调用其他函数
result = await some_async_function(data)
return result
```
**项目中的使用**`main.py`):
```python
@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 提供了应用启动和关闭事件:
```python
@app.on_event("startup")
async def startup_event():
"""应用启动时执行"""
print("应用启动")
@app.on_event("shutdown")
async def shutdown_event():
"""应用关闭时执行"""
print("应用关闭")
```
**项目中的使用**`main.py`):
```python
@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 允许在应用实例上存储状态:
```python
# 设置状态
app.state.my_data = "some value"
# 获取状态
my_data = app.state.my_data
```
**项目中的使用**`main.py`):
```python
# 在启动时设置
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 进行数据验证:
```python
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}
```
**项目中的潜在使用**(可以改进):
```python
# 可以定义请求模型
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 导入和初始化
```python
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 启动事件
```python
@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 路由处理
```python
@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)
```
**关键点**
1. `async def`:异步函数定义
2. `await request.json()`:异步获取 JSON 数据
3. `await anyio.to_thread.run_sync()`:在线程池中执行同步函数
4. `JSONResponse`:返回 JSON 响应
### 3. 任务队列机制
项目使用自定义的任务队列来处理请求:
```python
# 在 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
```
**工作流程**
1. 请求到达 `/webhook` 端点
2. 将任务放入队列
3. 后台线程处理任务
4. 等待结果返回
### 4. 操作映射机制
项目使用操作映射表来路由不同的操作:
```python
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 天)
1. **理解 FastAPI 基本概念**
- 阅读官方文档:https://fastapi.tiangolo.com/
- 理解路由、请求、响应的基本用法
2. **运行项目**
```bash
# 安装依赖
pip install -r requirements.txt
# 运行项目
python main.py
# 或
uvicorn main:app --reload
```
3. **访问 API 文档**
- 启动后访问:http://localhost:5003/docs
- 查看自动生成的 Swagger UI 文档
### 阶段 2:代码分析(2-3 天)
1. **分析 main.py**
- 理解应用初始化流程
- 理解路由处理逻辑
- 理解任务队列机制
2. **分析业务模块**
- 查看 `app/module/` 目录下的模块
- 理解操作映射机制
- 理解模块间的交互
3. **分析工具类**
- 查看 `app/utils/app_tools.py`
- 理解任务队列实现
- 理解日志记录机制
### 阶段 3:实践练习(3-5 天)
1. **添加新路由**
```python
@app.get("/health")
async def health_check():
return {"status": "ok"}
```
2. **添加数据验证**
```python
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()}
```
3. **添加错误处理**
```python
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 周)
1. **学习异步编程**
- 理解 `async/await`
- 理解 `asyncio`
- 理解并发处理
2. **学习 Pydantic**
- 数据验证
- 数据序列化
- 自定义验证器
3. **学习依赖注入**
- FastAPI 的依赖注入系统
- 数据库连接管理
- 认证和授权
---
## 常见问题解答
### Q1: FastAPI 和 Flask 的主要区别是什么?
**A:** 主要区别:
1. **性能**FastAPI 性能更高,支持异步
2. **类型验证**FastAPI 自动验证,Flask 需要手动
3. **API 文档**FastAPI 自动生成,Flask 需要手动编写
4. **异步支持**FastAPI 原生支持,Flask 需要额外库
### Q2: 为什么使用 `async def` 而不是 `def`
**A:**
- `async def` 允许使用 `await` 关键字
- 可以异步处理 I/O 操作(如网络请求、数据库查询)
- 提高并发性能
**示例**
```python
# 同步(阻塞)
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` 对象,但作用域是整个应用
**项目中的使用**
```python
# 启动时设置
app.state.logger = setup_global_logger(Config)
# 在路由中使用
logger = app.state.logger
```
### Q4: 如何处理同步函数?
**A:**
使用 `anyio.to_thread.run_sync()` 在线程池中执行同步函数:
```python
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()` 装饰器:
```python
@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`
```python
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 允许所有源
allow_credentials=True,
allow_methods=["*"], # 允许所有方法
allow_headers=["*"], # 允许所有头
)
```
### Q7: 如何添加认证?
**A:**
使用依赖注入:
```python
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"}
```
---
## 推荐资源
1. **官方文档**https://fastapi.tiangolo.com/
2. **中文文档**https://fastapi.tiangolo.com/zh/
3. **Pydantic 文档**https://docs.pydantic.dev/
4. **Uvicorn 文档**https://www.uvicorn.org/
---
## 总结
FastAPI 是一个现代、高性能的 Web 框架,特别适合构建 API。相比 Flask,它提供了:
1. **更好的性能**:异步支持,高性能
2. **自动验证**:基于类型提示的自动数据验证
3. **自动文档**:自动生成 API 文档
4. **更好的开发体验**:类型提示、IDE 支持
通过这个项目,你可以学习到:
- FastAPI 的基本用法
- 异步编程
- 任务队列机制
- 模块化架构设计
建议按照学习路径逐步深入,多实践、多思考,逐步掌握 FastAPI 的精髓。