How can I pass data from API endpoint (request) to middleware in FastAPI?

382 Views Asked by At

I would like to implement a logic where every API endpoint will have its API Credits (int), which I am going to use in an HTTP middleware to deduct credits from the user's balance.

I have searched a lot but have been unable to find any solution. Could anyone help me to achieve this? I am providing a pseudo-code to explain what I am trying to achieve.

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):

    # here I want to read API credits for request
    print(request.api_credit)

    response = await call_next(request)
    return response

    
@app.post("/myendpoint1")
async def myendpoint1():
    
    # define api credit for this endpoint
    api_credit = 2
    
    return {"message": "myendpoint"}


@app.post("/myendpoint2")
async def myendpoint2():
    
    # define api credit for this endpoint
    api_credit = 5
    
    return {"message": "myendpoint2"}
1

There are 1 best solutions below

0
On

As demonstrated in this answer, as well as here and here, one could use request.state to store arbitrary state and pass data between middlewares and FastAPI endpoints. Please refer to those answers for more details.

Working Example

from fastapi import FastAPI, Request


app = FastAPI()


@app.middleware("http")
async def some_middleware(request: Request, call_next):
    # initialize `api_credits` variable to None
    request.state.api_credits = None
    
    # process the request
    response = await call_next(request)
    
    # read API credits for this request
    print(request.state.api_credits)
    
    return response


@app.get("/")
async def main(request: Request):
    # set api credits for this request
    request.state.api_credits = 5
    return {"message": "ok"}