'how can i get all routes path from fast api?

I am new to FASTAPI and python .I need to get all the routes on my root path and show it to the user However I could not able to find a way to get all the paths recursively.The api is versioned with the help of VersionedFastAPI And the current code does not give the path inside version only returning generic ones . Code:

app = FastAPI()
router = APIRouter(
    tags=["utilities"]
)

@router.get("/")
def read_root(request: Request):
    url_list = [
        route.path
        for route in request.app.routes
    ]
    return { "endpoints": set(url_list) }

@app.get('/foo')
@version(1)
def foo():
    return "foo V1"

@app.get('/foo')
@version(2)
def foo():
    return "foo V2"

app = VersionedFastAPI(app, enable_latest=True, version_format='{major}', prefix_format='/v{major}')
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"]
)

app.include_router(router)

Code for getting the path list found under \ route

 url_list = [
            route.path
            for route in request.app.routes
        ]
        return { "endpoints": set(url_list) }

This returns only ["/v1/openapi.json","/v2/docs","/openapi.json","/v2/openapi.json","/v2","/","/redoc","/v1","/docs","/docs/oauth2-redirect","/v1/docs","/latest"] However /foo end point is missed here .Any clue on this will help .



Solution 1:[1]

Use as below. Make sure to call get_routes() before passing FastAPI instance to VersionedFastAPI. Also, in the example below, there is an endpoint (i.e., /greet) with no version. Thus, to make sure that such endpoints - if happen to be in the api - will be assigned a version, define a default value (might as well be the latest version) when attempting to get the version of the endpoint in version = getattr(route.endpoint, "_api_version", (2, 0)). By accessing the api documention at http://127.0.0.1:8000/v1/docs and http://127.0.0.1:8000/v2/docs, you will notice that /greet appears in both versions of the api; hence, it can be accessed by either using /v1/greet or /v2/greet. That is because it hadn't been given any specific version initially; however, using either of the above two, requests will be dispatched to the same path function.

from fastapi import FastAPI, APIRouter
from fastapi_versioning import VersionedFastAPI, version
import uvicorn


app = FastAPI()
router = APIRouter()
all_routes =[]


def get_routes():
    reserved_routes = ["/openapi.json", "/docs", "/docs/oauth2-redirect", "/redoc"]
    for route in app.routes:
        if route.path not in reserved_routes:
            if route.name is not None:
                version = getattr(route.endpoint, "_api_version", (2, 0))
                all_routes.append("/v" + str(version[0]) + route.path)


@router.get("/")
def index():
    return { "endpoints": all_routes }

 
@app.get("/foo")
@version(1)
def foo():
    return "foo v1"


@app.get("/foo")
@version(2)
def foo():
    return "foo v2"


@app.get("/items/{item_id}")
@version(2)
def get_item(item_id: int):
    return item_id
    

@app.get("/greet")
def greet_with_hi():
    return "Hi"


get_routes()
app = VersionedFastAPI(app, version_format='{major}',prefix_format='/v{major}')
app.include_router(router)


if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=8000)

Output (when accessing http://127.0.0.1:8000/):

{"endpoints":["/v1/foo","/v2/foo","/v2/items/{item_id}","/v2/greet"]}

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 Chris