00:00

文章目录

加载目录中...

python的contextvars模块及在FastAPI中使用(管理上下文变量)

contextvars是什么

contextvars 是 Python 3.7+ 引入的标准库模块,用于管理 上下文变量(Context Variables)。它解决了在异步或线程环境中共享状态时的“污染”问题。

  • 在传统的全局变量中,多个请求会互相干扰。
  • contextvars.ContextVar 保证每个 异步任务(task)线程 拥有自己独立的变量副本。

基础使用

  1. 创建一个ContextVar类的实例,request_id_var: ContextVar[str] = ContextVar('request_id')
  2. 使用.set()方法在上下文中注入值,print(context_var.set(1)) # 1
  3. 使用.get()方法获取值,print(context_var.get()) # 1

在fastapi中使用

我们需要给每一个请求一个request_id,并把它注入到上下文中。创建一个http中间件函数,在此函数中使用uuid生成一个request_id,并使用.set()方法将request_id注入到上下文中。这样我们在整个请求流程中就可以使用request_id_var.get()获取这个请求的request_id了。

from fastapi import FastAPI, Request
from contextvars import ContextVar
import uuid

app = FastAPI()

# 定义一个上下文变量
request_id_var: ContextVar[str] = ContextVar('request_id')  # 'request_id'只是一个标识,用于调试


@app.middleware('http')  # 将函数注册为HTTP请求/响应中间件,所有经过fastapi的HTTP请求都会先经过这个中间件
async def add_request_id(request: Request, call_next):
    request_id = str(uuid.uuid4())  # 使用uuid生成
    # 将该id绑定到当前异步上下文(当前的请求任务中),后续在该请求中,都可以通过.get()获取到这个id
    request_id_var.set(request_id)
    response = await call_next(request)
    response.headers['X-Request-Id'] = request_id
    return response


@app.get('/hello')
async def hello():
    request_id = request_id_var.get()
    return request_id
返回文章列表

评论区 0