简体   繁体   English

在 router.post fastapi 中捕获唯一 ID

[英]Capture unique id in router.post fastapi

I am trying to capture the time taken by api using fastapi in python with below method:我正在尝试使用以下方法在 python 中使用 fastapi 捕获 api 所花费的时间:

import string, time, random, logging
from starlette.requests import Request

@app.middleware("http")
async def log_requests(request: Request, call_next):
    idem = ''.join(random.choices(string.ascii_uppercase + string.digits, k=6))
    logger.info(f"rid={idem} start request path={request.url.path}")
    start_time = time.time()
    response = await call_next(request)
    process_time = (time.time() - start_time) * 1000
    formatted_process_time = '{0:.2f}'.format(process_time)
    logger.info(f"rid={idem} completed_in={formatted_process_time}ms status_code={response.status_code}")
    return response

I want to capture the unique id idem in @router.post section written as follows but it is giving error:我想在@router.post部分中捕获唯一的id idem ,如下所示,但它给出了错误:

import logging as log

@router.post("/infer/", response_description="AD Data Infer")
async def ad_infer_algorithm(ad_infer_config: ADInferConfigSchema = Body(...)):
  log.info("Executing AD Train Algorithm with config"+idem)
  return "2"

Kindly help请帮助

FastAPI has a state attribute on the request object. FastAPI 在request object 上有一个state属性。 This allows you to attach state to a request from a middleware, and then access that state in your controller (or in another middleware).这允许您将 state 附加到来自中间件的请求,然后在 controller(或其他中间件)中访问该 state。

Since you already have the request object available in your middleware, you can just attach idem to the request state there:由于您的中间件中已经有request object 可用,您只需将idem附加到请求 state 那里:

async def log_requests(request: Request, call_next):
    idem = ''.join(random.choices(string.ascii_uppercase + string.digits, k=6))
    request.state.idem = idem

(Side note: you can probably replace that random.choices call with secrets.token_urlsafe to get a randomly generated identifier (unless you need to control upper vs lower case identifiers - since you didn't include ascii_lowercase). (旁注:您可能可以将random.choices调用替换为secrets.token_urlsafe以获得随机生成的标识符(除非您需要控制大写和小写标识符 - 因为您没有包含 ascii_lowercase)。

You can then access that state in your view controller:然后,您可以在视图 controller 中访问该 state:

@router.post("/infer/", response_description="AD Data Infer")
async def ad_infer_algorithm(request: Request, ad_infer_config: ADInferConfigSchema = Body(...)):
  log.info("Executing AD Train Algorithm with config" + request.state.idem)
  return "2"

(Another side note: the logging commands should usually use placeholders ( %s ) and then the variables as arguments: log.info("Executing AD Train Algorithm with config %s", request.state.idem) (另一个注意事项:日志记录命令通常应使用占位符( %s ),然后将变量用作 arguments: log.info("Executing AD Train Algorithm with config %s", request.state.idem)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM