(六)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 的中间件与事件处理系统。如果你有任何问题或需要进一步的帮助,请随时联系我。

相关推荐
wxin_VXbishe21 分钟前
springboot合肥师范学院实习实训管理系统-计算机毕业设计源码31290
java·spring boot·python·spring·servlet·django·php
ITenderL27 分钟前
Python学习笔记-函数
python·学习笔记
zmjia11129 分钟前
全流程Python编程、机器学习与深度学习实践技术应用
python·深度学习·机器学习
_.Switch1 小时前
Python机器学习:自然语言处理、计算机视觉与强化学习
python·机器学习·计算机视觉·自然语言处理·架构·tensorflow·scikit-learn
JUNAI_Strive_ving1 小时前
番茄小说逆向爬取
javascript·python
彤银浦1 小时前
python学习记录7
python·学习
简单.is.good2 小时前
【测试】接口测试与接口自动化
开发语言·python
Envyᥫᩣ2 小时前
Python中的自然语言处理:从基础到高级
python·自然语言处理·easyui
哪 吒2 小时前
华为OD机试 - 几何平均值最大子数(Python/JS/C/C++ 2024 E卷 200分)
javascript·python·华为od
我是陈泽2 小时前
一行 Python 代码能实现什么丧心病狂的功能?圣诞树源代码
开发语言·python·程序员·编程·python教程·python学习·python教学