简体   繁体   中英

Capture unique id in router.post fastapi

I am trying to capture the time taken by api using fastapi in python with below method:

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:

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. This allows you to attach state to a request from a middleware, and then access that state in your controller (or in another middleware).

Since you already have the request object available in your middleware, you can just attach idem to the request state there:

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).

You can then access that state in your view controller:

@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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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