contextvars是什么
contextvars 是 Python 3.7+ 引入的标准库模块,用于管理 上下文变量(Context Variables)。它解决了在异步或线程环境中共享状态时的“污染”问题。
- 在传统的全局变量中,多个请求会互相干扰。
- 而
contextvars.ContextVar保证每个 异步任务(task) 或 线程 拥有自己独立的变量副本。
基础使用
- 创建一个ContextVar类的实例,
request_id_var: ContextVar[str] = ContextVar('request_id') - 使用
.set()方法在上下文中注入值,print(context_var.set(1)) # 1 - 使用
.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