FastAPI 中间件

中间件是一个函数,它在请求特定路径操作之前,以及在每个响应之后执行。

使用装饰器创建中间件

创建一个函数,在函数的顶部使用装饰器 @app.middleware("http").

函数参数如下:

  • request: Request

  • call_next 函数:这个函数将接收 request 作为参数,将 request 传递给相应的 路径操作,然后它将返回由相应的路径操作生成的 response.

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

app = FastAPI()

@app.middleware("http")
async def m2(request: Request, call_next):
    """第二个中间件"""
    print("第二个中间件 m2 ...request")

    response = await call_next(request)

    print("第二个中间件 m2 ...response")

    return response

@app.middleware("http")
async def m1(request: Request, call_next):
    """第一个中间件"""
    print("第一个中间件 m1 ...request")

    response = await call_next(request)

    print("第一个中间件 m1 ...response")

    return response

@app.get("/item/{item_id}")
async def item(item_id: int):
    print("请求get item id", item_id)
    return {"item_id": item_id}

if __name__ == '__main__':
    uvicorn.run(app)

运行结果:

python 复制代码
第一个中间件 m1 ...request
第二个中间件 m2 ...request
请求get item id 11111
第二个中间件 m2 ...response
第一个中间件 m1 ...response
INFO:     127.0.0.1:58664 - "GET /item/11111 HTTP/1.1" 200 OK

继承BaseHTTPMiddleware

1、定义中间件类:首先,你需要定义一个类,并继承自 starlette.middleware.base.BaseHTTPMiddleware。

2、实现 dispatch 方法:在你的类中,你需要实现 dispatch 方法。这个方法会在请求被传递给下一个中间件或最终的应用程序之前被调用。

3、注册你的中间件:在你的 FastAPI 应用中注册你的中间件。

创建my_middlewares包

示例:计算API接口调用耗时 中间件

创建CalculateTimeMiddleware.py 文件

python 复制代码
import time

from fastapi import Request, FastAPI
from starlette.middleware.base import BaseHTTPMiddleware

class CalculateTimeMiddleware(BaseHTTPMiddleware):
    """
    计算API接口耗时 单位: 秒
    """

    async def dispatch(self, request: Request, call_next):
        print("中间件: 计算API接口耗时...")
        start_time = time.perf_counter()
        response = await call_next(request)
        process_time = time.perf_counter() - start_time
        print(f"请求路径: {request.url.path}, 耗时: {process_time} 秒")
        return response

编写Main.py 文件

python 复制代码
import uvicorn
from fastapi import FastAPI
from starlette.requests import Request

from my_middlewares.AuthMiddleware import AuthMiddleware
from my_middlewares.CalculateTimeMiddleware import CalculateTimeMiddleware

app = FastAPI()

# 注册中间件
app.add_middleware(AuthMiddleware)  # type: ignore
app.add_middleware(CalculateTimeMiddleware) # type: ignore

@app.get("/item/{item_id}")
async def item(item_id: int, request: Request):
	# 获取上下文变量
    user_id = request.state.user_id
    print("user_id:", user_id)

    return {"item_id": item_id}

if __name__ == '__main__':
    uvicorn.run(app)

示例:中间件传递参数

使用上下文变量(Context Variables),FastAPI的Request对象允许你设置和获取上下文变量,这在多个中间件或路由处理器之间共享数据非常有用。

编写AuthMiddleware.py文件

python 复制代码
from starlette.middleware.base import BaseHTTPMiddleware

class AuthMiddleware(BaseHTTPMiddleware):
    """
    权限校验,并传递 user_id
    """

    async def dispatch(self, request, call_next):
        print("中间件: 传递 user_id ...")
        user_id="user001"
	
        # 设置上下文变量 将user_id存储在request.state中
        request.state.user_id = user_id

        response = await call_next(request)

        return response

运行结果:

python 复制代码
中间件: 计算API接口耗时...
中间件: 传递 user_id ...
user_id: user001
请求路径: /item/111, 耗时: 0.0006680000005871989 秒
相关推荐
余槐i1 天前
拆解 Agent 核心原理|从零动手实现简易 AI 智能体(三)
人工智能·python·fastapi·ai agent
醇氧1 天前
Git 合并冲突与`__pycache__` 的恩怨情仇
python·numpy·fastapi
甜到心里的蛋糕1 天前
如何用企业微信实现让微信收到通知实时通知
服务器·python·微信小程序·fastapi
basketball6162 天前
Python FastAPI 介绍以及常用方法
python·fastapi·vllm·ai infra
troy1283 天前
Codex 安全盲区:代码漏洞生成实测
windows·python·ci/cd·pycharm·django·github·fastapi
打工仔折腾 AI4 天前
FastAPI 从本机到生产服务器:Nginx+Gunicorn+Uvicorn 完整部署实录
人工智能·后端·python·nginx·fastapi·gunicorn
西安栈上月明软件科技4 天前
从 Linux 0.01 到 AI 开源:星图邻的开源实践
人工智能·自然语言处理·架构·开源·fastapi
troy1284 天前
Python 基础语法(九):Django/Flask/FastAPI 三大 Web 框架详细对比解析
python·jupyter·django·flask·github·fastapi
刚子编程6 天前
Ubuntu 22.04 Docker 从零部署全栈项目实录:Next.js + FastAPI + PostgreSQL 一次跑通
fastapi·nextjs·docker部署·全栈开发·ubuntu22.04
CSharp精选营7 天前
Ubuntu 22.04 Docker 从零部署全栈项目实录:Next.js + FastAPI + PostgreSQL 一次跑通
fastapi·nextjs·docker部署·全栈开发·ubuntu22.04