python-3.x 如何在FastAPI中列出所有已定义的URL路径?

axkjgtzd  于 2023-03-04  发布在  Python
关注(0)|答案(3)|浏览(192)

假设我有一个包含100多个API端点的FastAPI项目。如何列出所有API/路径?

4xy9mtcn

4xy9mtcn1#

要获取所有可能的URL模式,我们需要访问*定义的URL路由***,这是正在运行的应用示例的属性。
我们至少可以通过两种方式来实现
1.使用
FastAPI应用程序:当您可以访问FastAPi示例时,这非常方便
1.使用
Request**示例:当您可以访问传入的请求,但不能访问FastAPI示例时,这非常方便。

完整示例

from fastapi import FastAPI, Request

app = FastAPI()

@app.get(path="/", name="API Foo")
def foo():
    return {"message": "this is API Foo"}

@app.post(path="/bar", name="API Bar")
def bar():
    return {"message": "this is API Bar"}

# Using FastAPI instance
@app.get("/url-list")
def get_all_urls():
    url_list = [{"path": route.path, "name": route.name} for route in app.routes]
    return url_list

# Using Request instance
@app.get("/url-list-from-request")
def get_all_urls_from_request(request: Request):
    url_list = [
        {"path": route.path, "name": route.name} for route in request.app.routes
    ]
    return url_list
fzwojiic

fzwojiic2#

我试图提供一个编辑的原始答案,但不让我。
另一个使用案例:假设您不在主应用文件中,并且无法访问命名空间中的app。在这种情况下,Starlette文档说明我们还可以通过request.app请求访问应用示例。例如,如果在主文件中,您只有应用示例,并且不希望在主文件中有任何端点,但所有端点都位于单独的路由器中。
main.py 例如
我在utils路由器中有list_endpoints端点,为了能够列出所有的应用程序路由,我将执行以下操作:
utils.py 例如
请注意,我使用的不是app.routes,而是request.app.routes,我可以访问所有的路由。如果您现在访问/utils/list_endpoints,您将获得所有的路由。

1l5u6lss

1l5u6lss3#

当您只有一个应用程序时,公认的答案非常有效,但不幸的是,在我们的项目中,我们有许多子挂载的应用程序,这使得遍历方面有点棘手。

app.mount("/admin", admin_app)
...

我们也有很多路线,它们的非限定名称即使在一个应用程序中也可能相同,更不用说不同的了。所以我想了解一下所有路线及其匹配功能的概况。
这就是我如何处理它,希望它会对其他人有帮助。:)
很棒的框架,但是真的很想念django-extensions,它已经覆盖了这个,太糟心了,fastapi的土地上没有这样的东西。如果我错了,请纠正我!

from __future__ import annotations

from typing import Iterable

from app.main import app
from fastapi import FastAPI
from starlette.routing import Mount

def gen_routes(app: FastAPI | Mount) -> Iterable[tuple[str, str]]:
    for route in app.routes:
        if isinstance(route, Mount):
            yield from (
                (f"{route.path}{path}", name) for path, name in gen_routes(route)
            )
        else:
            yield (
                route.path,
                "{}.{}".format(route.endpoint.__module__, route.endpoint.__qualname__),
            )

def list_routes(app: FastAPI) -> None:
    import tabulate

    routes = sorted(set(gen_routes(app)))  # also readable enough
    print(tabulate.tabulate(routes, headers=["path", "full name"]))

if __name__ == "__main__":
    list_routes(app)

相关问题