(六)FastAPI的中间件与事件处理

FastAPI 是一个现代、快速、基于标准 Python 类型提示的 Web 框架,它以其高性能和易用性广受欢迎。在构建 Web 应用程序时,中间件和事件处理是两个非常重要的概念。它们使得我们能够在请求和响应的生命周期中插入自定义逻辑,并在应用程序启动或关闭时执行特定任务。

本文将详细介绍 FastAPI 的中间件与事件处理系统,帮助你深入理解并有效利用这些特性来构建高效、可维护的 Web 应用程序。

1. 什么是中间件

中间件(Middleware)是一个拦截 HTTP 请求和响应的组件,它在请求被处理之前和响应被发送之前执行。中间件通常用于执行跨路径操作函数的通用逻辑,比如日志记录、身份验证、修改请求或响应等。

在 FastAPI 中,中间件是通过装饰器@app.middleware("http")来定义的。

python 复制代码
from fastapi import FastAPI, Request
import time

app = FastAPI()

@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

在这个示例中,我们定义了一个中间件 add_process_time_header,它会记录每个请求的处理时间,并将其添加到响应头中。

1.1 中间件的执行顺序

如果注册了多个中间件,它们的执行顺序是按照注册的顺序执行。在请求阶段,中间件按注册顺序依次执行其"前"逻辑;在响应阶段,中间件按注册顺序的逆序依次执行其"后"逻辑。

python 复制代码
@app.middleware("http")
async def middleware_one(request: Request, call_next):
    print("Middleware One - Before")
    response = await call_next(request)
    print("Middleware One - After")
    return response

@app.middleware("http")
async def middleware_two(request: Request, call_next):
    print("Middleware Two - Before")
    response = await call_next(request)
    print("Middleware Two - After")
    return response

@app.middleware("http")
async def middleware_three(request: Request, call_next):
    print("Middleware Three - Before")
    response = await call_next(request)
    print("Middleware Three - After")
    return response

@app.get("/")
async def read_root():
    return {"message": "Hello, World!"}
执行顺序:
  1. Middleware One - Before
  2. Middleware Two - Before
  3. Middleware Three - Before
  4. 处理路径操作函数 read_root
  5. Middleware Three - After
  6. Middleware Two - After
  7. Middleware One - After

1.2 中间件的实际应用

中间件的实际应用场景包括:

  • 日志记录: 记录每个请求的详细信息,比如时间戳、请求方法、路径等。
  • 身份验证: 检查请求头中的认证信息,并在请求处理之前验证用户身份。
  • 修改请求/响应: 可以对请求对象进行预处理,或者在响应返回给客户端之前进行后处理。
示例:日志记录中间件
python 复制代码
from fastapi import FastAPI, Request
import logging

app = FastAPI()

logging.basicConfig(level=logging.INFO)

@app.middleware("http")
async def log_requests(request: Request, call_next):
    logging.info(f"Request: {request.method} {request.url}")
    response = await call_next(request)
    logging.info(f"Response status: {response.status_code}")
    return response

2. 什么是事件处理

事件处理(Event Handling)允许你在应用程序的生命周期中插入自定义逻辑,比如在应用启动和关闭时执行特定任务。这对于资源的初始化和清理非常有用。

在 FastAPI 中,可以使用 @app.on_event("startup")@app.on_event("shutdown") 装饰器来定义启动和关闭事件处理函数。

2.1 启动事件

启动事件处理函数在应用程序启动时执行,通常用于初始化数据库连接、启动后台任务等。

python 复制代码
@app.on_event("startup")
async def startup_event():
    print("Application is starting up!")
    # 初始化数据库连接等

2.2 关闭事件

关闭事件处理函数在应用程序关闭时执行,通常用于关闭数据库连接、清理资源等。

python 复制代码
@app.on_event("shutdown")
async def shutdown_event():
    print("Application is shutting down!")
    # 关闭数据库连接等

2.3 实际应用场景

  • 数据库连接管理: 在应用启动时建立数据库连接,在应用关闭时断开数据库连接。

  • 后台任务: 在应用启动时启动定时任务或后台处理任务,在应用关闭时停止这些任务。

  • 资源清理: 在应用关闭时清理缓存或临时文件等。

示例:完整的事件处理
python 复制代码
from fastapi import FastAPI

app = FastAPI()

@app.on_event("startup")
async def startup_event():
    print("Starting up...")
    # 这里可以初始化数据库连接等

@app.on_event("shutdown")
async def shutdown_event():
    print("Shutting down...")
    # 这里可以关闭数据库连接等

@app.get("/")
async def read_root():
    return {"message": "Hello, World!"}

3. 依赖注入与中间件、事件处理结合

FastAPI 的依赖注入系统也可以与中间件和事件处理结合使用,以实现更复杂的应用逻辑。例如,可以通过依赖注入来管理数据库连接的生命周期,并在中间件或事件处理函数中使用这些依赖项。

python 复制代码
from fastapi import Depends, FastAPI
import databases

app = FastAPI()

DATABASE_URL = "sqlite:///./test.db"
database = databases.Database(DATABASE_URL)

async def get_db():
    await database.connect()
    try:
        yield database
    finally:
        await database.disconnect()

@app.middleware("http")
async def db_session_middleware(request: Request, call_next):
    request.state.db = database
    response = await call_next(request)
    return response

@app.get("/items/")
async def read_items(db: databases.Database = Depends(get_db)):
    query = "SELECT * FROM items"
    return await db.fetch_all(query)

@app.on_event("startup")
async def startup_event():
    await database.connect()

@app.on_event("shutdown")
async def shutdown_event():
    await database.disconnect()

在这个示例中,我们结合了中间件、事件处理和依赖注入来管理数据库连接。中间件 db_session_middleware 将数据库连接添加到请求状态中,依赖注入函数 get_db 管理数据库连接的生命周期,启动和关闭事件处理函数 startup_eventshutdown_event 在应用启动和关闭时管理数据库连接。

4. 总结

FastAPI 提供了强大的中间件和事件处理系统,使得我们可以在请求和响应的生命周期中插入自定义逻辑,并在应用程序启动或关闭时执行特定任务。通过合理使用中间件和事件处理,可以大大提升应用程序的可维护性和可扩展性。

希望这篇文章能帮助你深入理解 FastAPI 的中间件与事件处理系统。如果你有任何问题或需要进一步的帮助,请随时联系我。

相关推荐
傻啦嘿哟26 分钟前
如何使用 Python 开发一个简单的文本数据转换为 Excel 工具
开发语言·python·excel
B站计算机毕业设计超人32 分钟前
计算机毕业设计SparkStreaming+Kafka旅游推荐系统 旅游景点客流量预测 旅游可视化 旅游大数据 Hive数据仓库 机器学习 深度学习
大数据·数据仓库·hadoop·python·kafka·课程设计·数据可视化
IT古董1 小时前
【人工智能】Python在机器学习与人工智能中的应用
开发语言·人工智能·python·机器学习
湫ccc1 小时前
《Python基础》之pip换国内镜像源
开发语言·python·pip
hakesashou1 小时前
Python中常用的函数介绍
java·网络·python
菜鸟的人工智能之路2 小时前
极坐标气泡图:医学数据分析的可视化新视角
python·数据分析·健康医疗
菜鸟学Python2 小时前
Python 数据分析核心库大全!
开发语言·python·数据挖掘·数据分析
小白不太白9502 小时前
设计模式之 责任链模式
python·设计模式·责任链模式
喜欢猪猪2 小时前
Django:从入门到精通
后端·python·django
糖豆豆今天也要努力鸭2 小时前
torch.__version__的torch版本和conda list的torch版本不一致
linux·pytorch·python·深度学习·conda·torch