简体   繁体   中英

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

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)

You may not be able to accomplish exactly what you need, though you can get very close with the standard framework (ie 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/


NB 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 (ie no fancy alterations of the framework). Still, if you know your prefix, you can remove it from the path (it's just a string).

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