python 如何从FastAPI应用程序获取每个路由路径?

yc0p9oo0  于 2023-05-21  发布在  Python
关注(0)|答案(1)|浏览(474)

我是FastAPI和Python的新手。我需要获取根路径上的所有路由并将其显示给用户。但是,我无法找到一种方法来递归地获得所有路径。API是在VersionedFastAPI的帮助下进行版本化的,当前代码没有给予版本内的路径;它只返回通用的。
FastAPI后端:

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)

获取\路由下的路径列表的代码

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

这只返回:

["/v1/openapi.json","/v2/docs","/openapi.json","/v2/openapi.json","/v2","/","/redoc","/v1","/docs","/docs/oauth2-redirect","/v1/docs","/latest"]

但是,缺少/foo端点。任何线索都会有帮助。

wbgh16ku

wbgh16ku1#

在下面的示例中,请确保在将FastAPI示例传递给VersionedFastAPI之前调用get_routes()。此外,还有一个端点(即/greet)没有指定版本。因此,为了确保这样的端点(如果恰好存在于您的API中)将被分配一个版本,当尝试在这行代码中获取端点的版本时,您需要定义一个默认值(也可能是最新版本):version = getattr(route.endpoint, "_api_version", (2, 0))。通过访问http://127.0.0.1:8000/v1/docshttp://127.0.0.1:8000/v2/docs上的OpenAPI/Swagger UI文档,您会注意到/greet出现在两个版本的API中;因此,可以使用/v1/greet/v2/greet访问它。这是因为它最初没有给出任何特定的版本;然而,使用任一端点,请求将被分派到相同的路径操作功能。

工作示例

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)

输出(访问http://127.0.0.1:8000/时):

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

This answer在检索原始路由路径方面也可能有所帮助。

相关问题