如何在函数中访问fastapi中间件中定义的request_id
How to access request_id defined in fastapi middleware in function
嗨,我的中间件是这样写的
@app.middleware("http")
async def request_middleware(request, call_next):
end_point = request.url.path
global request_id
request_id = get_request_id()
with logger.contextualize(request_id=request_id, end_point=end_point):
logger.info("----------Request started----------")
try:
response = await call_next(request)
except Exception as ex:
logger.error(f"Request failed: {ex}")
response = JSONResponse()
finally:
response.headers["X-Request-Id"] = request_id
logger.info("----------Request ended----------")
return response
我希望中间件中定义的 request_id 可以在定义的其他函数中访问,我们该怎么做?
您可以使用不在异步任务之间共享的上下文变量来代替全局变量request_id
from contextvars import ContextVar
req_id: ContextVar[str] = ContextVar('req_id', default='')
# Inside your middleware
req_id.set(get_request_id())
# Inside other functions, even different files, you import that variable
req_id.get()
另2个解决方案:
- 在你的中间件中存储
request.state
中的数据,然后在视图函数中访问request.state
。 https://fastapi.tiangolo.com/tutorial/sql-databases/?h=request.#about-requeststate 中的更多信息
- 或者使用starlette-context,就像flask中的
g
一样,这样就简单多了
from starlette_context import context
from starlette_context.middleware import RawContextMiddleware
app.add_middleware(RawContextMiddleware)
@app.middleware("http")
async def request_middleware(request, call_next):
request_id = get_request_id()
context['request_id'] = request_id
@router.post('foobar')
async def foorbar():
context['request_id']
嗨,我的中间件是这样写的
@app.middleware("http")
async def request_middleware(request, call_next):
end_point = request.url.path
global request_id
request_id = get_request_id()
with logger.contextualize(request_id=request_id, end_point=end_point):
logger.info("----------Request started----------")
try:
response = await call_next(request)
except Exception as ex:
logger.error(f"Request failed: {ex}")
response = JSONResponse()
finally:
response.headers["X-Request-Id"] = request_id
logger.info("----------Request ended----------")
return response
我希望中间件中定义的 request_id 可以在定义的其他函数中访问,我们该怎么做?
您可以使用不在异步任务之间共享的上下文变量来代替全局变量request_id
from contextvars import ContextVar
req_id: ContextVar[str] = ContextVar('req_id', default='')
# Inside your middleware
req_id.set(get_request_id())
# Inside other functions, even different files, you import that variable
req_id.get()
另2个解决方案:
- 在你的中间件中存储
request.state
中的数据,然后在视图函数中访问request.state
。 https://fastapi.tiangolo.com/tutorial/sql-databases/?h=request.#about-requeststate 中的更多信息
- 或者使用starlette-context,就像flask中的
g
一样,这样就简单多了
from starlette_context import context
from starlette_context.middleware import RawContextMiddleware
app.add_middleware(RawContextMiddleware)
@app.middleware("http")
async def request_middleware(request, call_next):
request_id = get_request_id()
context['request_id'] = request_id
@router.post('foobar')
async def foorbar():
context['request_id']