'How to get defined route paths in FastAPI?

I have my FastAPI app define in server.py

app = FastAPI(
debug=True, title="Microservice for APIs",
description="REST APIs",
version="0.0.1",
openapi_url="/v3/api-docs",
middleware=[
    Middleware(AuthorizationMiddleware, authorizor=Auth())
]) 

In __init__.py, I have routes defined

from fastapi import APIRouter
api_router = APIRouter()
api_router.include_router(impl_controller.router, prefix="/impl/data",
                      tags=["APIs for Impl Management"])

In impl_controller.py, I have define routes like this

@router.get('{id}/get_all')
def hello_world():
    return {"msg": "Hello World"}

@router.get('{id}/get_last')
def test():
    return {"msg": "test"}

In the middleware, I'm trying to get request route and not the URL

def check_for_api_access(self, request: Request):
    request_path = request.scope['path']
    # route_path = request.scope['endpoint']  # This does not exists

    url_list = [
        {'path': route.path, 'name': route.name}
        for route in request.app.routes
    ]

Result I'm expecting is: {id}/get_all for 1st request and {id}/get_last for 2nd request.

I'm able to get list of all paths in url_list but I want route path for the specific request

Tried solution provided here: https://github.com/tiangolo/fastapi/issues/486 that also not working for me



Solution 1:[1]

Try this:

def check_for_api_access(self, request: Request):
   api_route = next(item for item in request.app.routes if isinstance(item, APIRoute) and item.dependant.cache_key[0] == request.scope['endpoint'])
   print(api_route.path)

Solution 2:[2]

You may not be able to accomplish exactly what you need, though you can get very close with the standard framework (i.e. no fancy alterations of the framework).

In the middleware, you can access the request directly. This way, you'll be able to inspect the requested url, as documented in https://fastapi.tiangolo.com/advanced/using-request-directly/?h=request . The attributes that are accessible are described here https://www.starlette.io/requests/


N.B. Since you posted just snippets, it's very difficult to say where values/variables come from.

In your case, it's dead simple what is not working. If you looked at the urls I posted, the starlette docs, shows the attributes that you can access from a request. This contains exactly the attribute you are looking for.

Basically, change request_path = request.scope['path'] into request_path = request.url.path. If you have a prefix, then you'll also get that and that's why I said You may not be able to accomplish exactly what you need, though you can get very close with the standard framework (i.e. no fancy alterations of the framework). Still, if you know your prefix, you can remove it from the path (it's just a string).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 RKO
Solution 2 E_net4 - Krabbe mit Hüten