Files
jdy_fastapi/FASTAPI_LEARNING.md
T
2025-11-07 17:48:49 +08:00

16 KiB
Raw Blame History

FastAPI 学习文档

📚 目录

  1. FastAPI 简介
  2. Flask vs FastAPI 对比
  3. FastAPI 核心概念
  4. 项目中的 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 写法

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 支持异步函数,使用 asyncawait

@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:请求对象,用于访问请求信息
  • JSONResponseJSON 响应类

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)

关键点

  1. async def:异步函数定义
  2. await request.json():异步获取 JSON 数据
  3. await anyio.to_thread.run_sync():在线程池中执行同步函数
  4. 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

工作流程

  1. 请求到达 /webhook 端点
  2. 将任务放入队列
  3. 后台线程处理任务
  4. 等待结果返回

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 天)

  1. 理解 FastAPI 基本概念

  2. 运行项目

    # 安装依赖
    pip install -r requirements.txt
    
    # 运行项目
    python main.py
    # 或
    uvicorn main:app --reload
    
  3. 访问 API 文档

阶段 2:代码分析(2-3 天)

  1. 分析 main.py

    • 理解应用初始化流程
    • 理解路由处理逻辑
    • 理解任务队列机制
  2. 分析业务模块

    • 查看 app/module/ 目录下的模块
    • 理解操作映射机制
    • 理解模块间的交互
  3. 分析工具类

    • 查看 app/utils/app_tools.py
    • 理解任务队列实现
    • 理解日志记录机制

阶段 3:实践练习(3-5 天)

  1. 添加新路由

    @app.get("/health")
    async def health_check():
        return {"status": "ok"}
    
  2. 添加数据验证

    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. 添加错误处理

    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 操作(如网络请求、数据库查询)
  • 提高并发性能

示例

# 同步(阻塞)
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"}

推荐资源

  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 的精髓。