497 lines
9.0 KiB
Markdown
497 lines
9.0 KiB
Markdown
# FastAPI 快速参考指南
|
||
|
||
## 🚀 快速开始
|
||
|
||
### 最小示例
|
||
|
||
```python
|
||
from fastapi import FastAPI
|
||
|
||
app = FastAPI()
|
||
|
||
@app.get("/")
|
||
async def read_root():
|
||
return {"Hello": "World"}
|
||
|
||
@app.get("/items/{item_id}")
|
||
async def read_item(item_id: int):
|
||
return {"item_id": item_id}
|
||
```
|
||
|
||
### 运行应用
|
||
|
||
```bash
|
||
# 方式 1:使用 uvicorn
|
||
uvicorn main:app --reload
|
||
|
||
# 方式 2:在代码中运行
|
||
if __name__ == '__main__':
|
||
import uvicorn
|
||
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
||
```
|
||
|
||
---
|
||
|
||
## 📝 路由定义
|
||
|
||
### HTTP 方法
|
||
|
||
```python
|
||
@app.get("/items") # GET 请求
|
||
@app.post("/items") # POST 请求
|
||
@app.put("/items/{id}") # PUT 请求
|
||
@app.delete("/items/{id}") # DELETE 请求
|
||
@app.patch("/items/{id}") # PATCH 请求
|
||
```
|
||
|
||
### 路径参数
|
||
|
||
```python
|
||
@app.get("/items/{item_id}")
|
||
async def read_item(item_id: int):
|
||
return {"item_id": item_id}
|
||
|
||
# 多个路径参数
|
||
@app.get("/users/{user_id}/items/{item_id}")
|
||
async def read_user_item(user_id: int, item_id: int):
|
||
return {"user_id": user_id, "item_id": item_id}
|
||
```
|
||
|
||
### 查询参数
|
||
|
||
```python
|
||
@app.get("/items")
|
||
async def read_items(skip: int = 0, limit: int = 10):
|
||
return {"skip": skip, "limit": limit}
|
||
|
||
# 可选参数
|
||
@app.get("/items")
|
||
async def read_items(q: str = None):
|
||
return {"q": q}
|
||
```
|
||
|
||
### 请求体
|
||
|
||
```python
|
||
from pydantic import BaseModel
|
||
|
||
class Item(BaseModel):
|
||
name: str
|
||
price: float
|
||
description: str = None # 可选字段
|
||
|
||
@app.post("/items")
|
||
async def create_item(item: Item):
|
||
return item
|
||
```
|
||
|
||
---
|
||
|
||
## 🔧 请求和响应
|
||
|
||
### 获取请求数据
|
||
|
||
```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
|
||
|
||
# 表单数据
|
||
form_data = await request.form()
|
||
|
||
# 文件上传
|
||
files = await request.form()
|
||
```
|
||
|
||
### 响应类型
|
||
|
||
```python
|
||
from fastapi.responses import JSONResponse, HTMLResponse, PlainTextResponse
|
||
|
||
@app.get("/json")
|
||
async def json_response():
|
||
return JSONResponse({"message": "Hello"})
|
||
|
||
@app.get("/html")
|
||
async def html_response():
|
||
return HTMLResponse("<h1>Hello</h1>")
|
||
|
||
@app.get("/text")
|
||
async def text_response():
|
||
return PlainTextResponse("Hello")
|
||
```
|
||
|
||
### 状态码
|
||
|
||
```python
|
||
from fastapi import status
|
||
|
||
@app.post("/items", status_code=status.HTTP_201_CREATED)
|
||
async def create_item(item: Item):
|
||
return item
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ 数据验证(Pydantic)
|
||
|
||
### 基本模型
|
||
|
||
```python
|
||
from pydantic import BaseModel, Field
|
||
|
||
class User(BaseModel):
|
||
name: str
|
||
age: int = Field(gt=0, le=120) # 年龄必须大于 0,小于等于 120
|
||
email: str = Field(..., regex="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")
|
||
```
|
||
|
||
### 嵌套模型
|
||
|
||
```python
|
||
class Address(BaseModel):
|
||
street: str
|
||
city: str
|
||
|
||
class User(BaseModel):
|
||
name: str
|
||
address: Address
|
||
```
|
||
|
||
### 列表和字典
|
||
|
||
```python
|
||
class Item(BaseModel):
|
||
tags: list[str] = []
|
||
metadata: dict[str, str] = {}
|
||
```
|
||
|
||
---
|
||
|
||
## 🔐 依赖注入
|
||
|
||
### 基本依赖
|
||
|
||
```python
|
||
from fastapi import Depends
|
||
|
||
def get_db():
|
||
db = "database"
|
||
yield db
|
||
# 清理代码
|
||
|
||
@app.get("/items")
|
||
async def read_items(db: str = Depends(get_db)):
|
||
return {"db": db}
|
||
```
|
||
|
||
### 类依赖
|
||
|
||
```python
|
||
class Database:
|
||
def get_data(self):
|
||
return "data"
|
||
|
||
def get_database():
|
||
return Database()
|
||
|
||
@app.get("/items")
|
||
async def read_items(db: Database = Depends(get_database)):
|
||
return db.get_data()
|
||
```
|
||
|
||
---
|
||
|
||
## 🛡️ 错误处理
|
||
|
||
### HTTP 异常
|
||
|
||
```python
|
||
from fastapi import HTTPException
|
||
|
||
@app.get("/items/{item_id}")
|
||
async def read_item(item_id: int):
|
||
if item_id not in items:
|
||
raise HTTPException(status_code=404, detail="Item not found")
|
||
return {"item_id": item_id}
|
||
```
|
||
|
||
### 自定义异常处理器
|
||
|
||
```python
|
||
from fastapi import Request
|
||
from fastapi.responses import JSONResponse
|
||
|
||
@app.exception_handler(ValueError)
|
||
async def value_error_handler(request: Request, exc: ValueError):
|
||
return JSONResponse(
|
||
status_code=400,
|
||
content={"message": str(exc)}
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 异步编程
|
||
|
||
### 异步函数
|
||
|
||
```python
|
||
import asyncio
|
||
|
||
@app.get("/async")
|
||
async def async_endpoint():
|
||
await asyncio.sleep(1) # 模拟异步操作
|
||
return {"message": "Done"}
|
||
```
|
||
|
||
### 在线程池中运行同步函数
|
||
|
||
```python
|
||
import anyio
|
||
|
||
def sync_function(data):
|
||
# 同步耗时操作
|
||
return result
|
||
|
||
@app.post("/sync-in-async")
|
||
async def sync_in_async(data: dict):
|
||
result = await anyio.to_thread.run_sync(sync_function, data)
|
||
return result
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 应用状态和生命周期
|
||
|
||
### 应用状态
|
||
|
||
```python
|
||
# 设置状态
|
||
app.state.my_data = "value"
|
||
|
||
# 获取状态
|
||
my_data = app.state.my_data
|
||
```
|
||
|
||
### 启动和关闭事件
|
||
|
||
```python
|
||
@app.on_event("startup")
|
||
async def startup_event():
|
||
# 启动时执行
|
||
print("应用启动")
|
||
|
||
@app.on_event("shutdown")
|
||
async def shutdown_event():
|
||
# 关闭时执行
|
||
print("应用关闭")
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 中间件
|
||
|
||
### 添加中间件
|
||
|
||
```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
|
||
```
|
||
|
||
### CORS 中间件
|
||
|
||
```python
|
||
from fastapi.middleware.cors import CORSMiddleware
|
||
|
||
app.add_middleware(
|
||
CORSMiddleware,
|
||
allow_origins=["*"],
|
||
allow_credentials=True,
|
||
allow_methods=["*"],
|
||
allow_headers=["*"],
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 📚 项目中的实际应用
|
||
|
||
### 1. 应用初始化(main.py)
|
||
|
||
```python
|
||
app = FastAPI(title="简道云FastAPI服务")
|
||
|
||
@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()
|
||
```
|
||
|
||
### 2. 路由处理
|
||
|
||
```python
|
||
@app.post("/webhook")
|
||
async def webhook(request: Request):
|
||
# 获取状态
|
||
logger = app.state.logger
|
||
app_tools = app.state.app_tools
|
||
|
||
# 获取请求数据
|
||
data = await request.json()
|
||
header = request.headers
|
||
|
||
# 处理逻辑
|
||
# ...
|
||
|
||
# 返回响应
|
||
return JSONResponse(result)
|
||
```
|
||
|
||
### 3. 任务队列集成
|
||
|
||
```python
|
||
# 将任务放入队列
|
||
response_queue = app_tools.enqueue_task(handler, data)
|
||
|
||
# 等待结果(在线程池中执行)
|
||
result = await anyio.to_thread.run_sync(response_queue.get)
|
||
```
|
||
|
||
---
|
||
|
||
## 🔍 调试技巧
|
||
|
||
### 1. 查看自动生成的文档
|
||
|
||
启动应用后访问:
|
||
- Swagger UI: http://localhost:8000/docs
|
||
- ReDoc: http://localhost:8000/redoc
|
||
|
||
### 2. 打印请求信息
|
||
|
||
```python
|
||
@app.post("/webhook")
|
||
async def webhook(request: Request):
|
||
print(f"Method: {request.method}")
|
||
print(f"URL: {request.url}")
|
||
print(f"Headers: {dict(request.headers)}")
|
||
data = await request.json()
|
||
print(f"Body: {data}")
|
||
```
|
||
|
||
### 3. 使用日志
|
||
|
||
```python
|
||
import logging
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
@app.post("/webhook")
|
||
async def webhook(request: Request):
|
||
logger.info("收到请求")
|
||
logger.debug(f"请求数据: {data}")
|
||
```
|
||
|
||
---
|
||
|
||
## 📖 常用模式
|
||
|
||
### 1. 操作映射模式(项目中使用)
|
||
|
||
```python
|
||
def get_action_map() -> dict:
|
||
return {
|
||
'action1': handler1,
|
||
'action2': handler2,
|
||
}
|
||
|
||
@app.post("/api")
|
||
async def api(request: Request):
|
||
action_map = get_action_map()
|
||
action = request.headers.get('Action')
|
||
handler = action_map.get(action)
|
||
if handler:
|
||
result = handler(data)
|
||
return JSONResponse(result)
|
||
```
|
||
|
||
### 2. 统一错误处理
|
||
|
||
```python
|
||
@app.exception_handler(Exception)
|
||
async def global_exception_handler(request: Request, exc: Exception):
|
||
logger.error(f"未处理的异常: {exc}")
|
||
return JSONResponse(
|
||
status_code=500,
|
||
content={"message": "内部服务器错误"}
|
||
)
|
||
```
|
||
|
||
### 3. 请求验证
|
||
|
||
```python
|
||
from pydantic import BaseModel, validator
|
||
|
||
class WebhookData(BaseModel):
|
||
api_key: str
|
||
entry_id: str
|
||
data_id: str
|
||
|
||
@validator('api_key')
|
||
def validate_api_key(cls, v):
|
||
if not v:
|
||
raise ValueError('api_key 不能为空')
|
||
return v
|
||
|
||
@app.post("/webhook")
|
||
async def webhook(data: WebhookData):
|
||
# 数据已自动验证
|
||
return {"received": data.dict()}
|
||
```
|
||
|
||
---
|
||
|
||
## 🎓 学习检查清单
|
||
|
||
- [ ] 理解 FastAPI 基本概念
|
||
- [ ] 能够创建简单的路由
|
||
- [ ] 理解异步编程(async/await)
|
||
- [ ] 掌握 Pydantic 数据验证
|
||
- [ ] 理解依赖注入
|
||
- [ ] 能够处理错误
|
||
- [ ] 理解应用状态和生命周期
|
||
- [ ] 能够添加中间件
|
||
- [ ] 理解项目中的任务队列机制
|
||
- [ ] 能够添加新的路由和功能
|
||
|
||
---
|
||
|
||
## 📚 相关资源
|
||
|
||
- **FastAPI 官方文档**: https://fastapi.tiangolo.com/
|
||
- **FastAPI 中文文档**: https://fastapi.tiangolo.com/zh/
|
||
- **Pydantic 文档**: https://docs.pydantic.dev/
|
||
- **Uvicorn 文档**: https://www.uvicorn.org/
|
||
- **Python 异步编程**: https://docs.python.org/3/library/asyncio.html
|
||
|
||
---
|
||
|
||
**提示**: 这个快速参考指南可以作为日常开发的速查手册。建议结合 `FASTAPI_LEARNING.md` 深入学习。
|
||
|