【问题标题】:How can I get every route path from FastAPI app?如何从快速 api 获取所有路由路径?
【发布时间】:2022-01-27 17:26:57
【问题描述】:

我是 FASTAPI 和 python 的新手。我需要获取根路径上的所有路由并将其显示给用户但是我无法找到一种方法来递归地获取所有路径。api 的版本是VersionedFastAPI 的帮助并且当前代码没有给出版本内部的路径,只返回通用的。 代码:

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 端点。任何有关这方面的线索都会有所帮助。

【问题讨论】:

    标签: python fastapi


    【解决方案1】:

    如下使用。确保在将 FastAPI 实例传递给 VersionedFastAPI 之前调用 get_routes()。此外,在下面的示例中,有一个没有版本的端点(即/greet)。因此,为确保此类端点(如果碰巧在 api 中)将被分配一个版本,请在尝试获取 version = getattr(route.endpoint, "_api_version", (2, 0)) 中的端点版本时定义一个默认值(也可能是最新版本)。通过访问http://127.0.0.1:8000/v1/docs 和http://127.0.0.1:8000/v2/docs 的api 文档,您会注意到/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"]}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-17
      • 2016-11-16
      • 1970-01-01
      • 2014-10-16
      • 1970-01-01
      • 2021-10-14
      • 2017-01-02
      相关资源
      最近更新 更多