question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to access route parameter in a middleware?

See original GitHub issue

First check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn’t find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google “How to X in FastAPI” and didn’t find any information.
  • I already read and followed all the tutorial in the docs and didn’t find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.
  • After submitting this, I commit to one of:
    • Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
    • I already hit the “watch” button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
    • Implement a Pull Request for a confirmed bug.

I am trying to add a custom parameter in the route and like to access it in a middleware. eg.

from fastapi import FastAPI
app = FastAPI()

@app.get("/", action=['search'])  # I am interested in accessing the `action` parameter in a middleware
def read_root():
    return {"Hello": "World"}

Here’s what I have done so far.

from typing import Callable, List, Any

import uvicorn
from fastapi.routing import APIRoute
from starlette.requests import Request
from starlette.responses import Response

from starlette.middleware.base import (
    BaseHTTPMiddleware,
    RequestResponseEndpoint
)

from fastapi import FastAPI, APIRouter


class AuditHTTPMiddleware(BaseHTTPMiddleware):
    # I want the `action` parameter from the route to be accessible in this middleware
    async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response:
        response = await call_next(request)
        return response


class CustomAPIRoute(APIRoute):
    def __init__(self, path: str, endpoint: Callable, *, action: List[str] = None, **kwargs) -> None:
        super(CustomAPIRoute, self).__init__(path, endpoint, **kwargs)
        self.action = action


class CustomAPIRouter(APIRouter):
    def __init__(self):
        super(CustomAPIRouter, self).__init__()
        self.route_class = CustomAPIRoute

    def add_api_route(self, path: str, endpoint: Callable, *, action: List[str] = None, **kwargs) -> None:
        route = self.route_class(path=path, endpoint=endpoint, action=action, **kwargs)
        self.routes.append(route)

    def api_route(self, path: str, *, action: List[str] = None, **kwargs) -> Callable:
        def decorator(func: Callable) -> Callable:
            self.add_api_route(path, func, action=action, **kwargs)
            return func

        return decorator

    def get(self, path: str, *, action: List[str] = None, **kwargs) -> Callable:
        return self.api_route(path, action=action, **kwargs)


router = CustomAPIRouter()


@router.get('/', action=['Search'], tags=["Current tag"])
def get_data():
    return {}


if __name__ == '__main__':
    app = FastAPI()

    app.add_middleware(AuditHTTPMiddleware)
    app.include_router(prefix='', router=router)
    uvicorn.run(app, host="0.0.0.0", port=9002)

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
tiangolocommented, May 10, 2021

I think this use case could be easily handled without a middleware, using normal dependencies, here’s an example:

from fastapi import FastAPI, Depends


class Action:
    def __init__(self, action: str):
        self.action = action

    def __call__(self):
        # action parameter available here, do anything you want with audit here
        # before the response
        print(self.action)
        yield
        # or after the response
        print(self.action)


app = FastAPI()


@app.get("/", dependencies=[Depends(Action("search"))])
def home():
    return {"Hello": "World"}

It would probably not be a good idea to do that in a middleware as it doesn’t have access to any info you put there, as @phy25 says. Or it would require getting the data after the response is created, as @Kludex mentions, but then that requires executing the whole path operation function before being able to access the data in the middleware, and by that point, there’s no way to undo any computation that is already done. And that computation could be costly, or that could have saved data records that you wanted to prevent, or could have sent money that you didn’t want to be sent. 😅

2reactions
phy25commented, Aug 12, 2020

Middleware is called before router kicks in. You should instead try incorpating the logic into a Depends or reading query params from the original request yourself.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Laravel middleware get route parameter - Stack Overflow
I can use $requests->club to get parameter . Thanks everyone. Share.
Read more >
Accessing route values in endpoint middleware in ASP.NET ...
In this post I describe how you can access the route values from middleware when using endpoint routing in ASP.NET Core 3.0.
Read more >
[L5] How to get url parameters at middleware - Laracasts
[L5] How to get url parameters at middleware. I have these routes. Copy Code Route::group(['prefix' => '{id}/questions', 'middleware' => 'groupExists'], ...
Read more >
Laravel Get Route Parameters In Middleware Example
Laravel Get Route Parameters in middleware Example · app/Http/routes.php · Laravel route is generally annotated with main code curly braces · app/Http/Middleware/ ...
Read more >
Middleware - Laravel - The PHP Framework For Web Artisans
Assigning Middleware To Routes. If you would like to assign middleware to specific routes, you should first assign the middleware a key in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found