获取Flask应用中定义的所有路线的列表


145

我有一个复杂的基于Flask的Web应用程序。有很多具有视图功能的单独文件。它们的URL由@app.route('/...')装饰器定义。有没有办法获取我的应用中已声明的所有路线的列表?也许有一些方法可以调用该app对象?

Answers:


152

应用程序的所有路由都存储在app.url_map的实例上werkzeug.routing.Map。您可以Rule使用以下iter_rules方法遍历实例:

from flask import Flask, url_for

app = Flask(__name__)

def has_no_empty_params(rule):
    defaults = rule.defaults if rule.defaults is not None else ()
    arguments = rule.arguments if rule.arguments is not None else ()
    return len(defaults) >= len(arguments)


@app.route("/site-map")
def site_map():
    links = []
    for rule in app.url_map.iter_rules():
        # Filter out rules we can't navigate to in a browser
        # and rules that require parameters
        if "GET" in rule.methods and has_no_empty_params(rule):
            url = url_for(rule.endpoint, **(rule.defaults or {}))
            links.append((url, rule.endpoint))
    # links is now a list of url, endpoint tuples

有关更多信息,请参见显示指向创建的新网页的链接


甜!除了我对这条线有问题url = url_for(rule.endpoint)。我刚遇到这个错误BuildError: ('DeleteEvent', {}, None)。取而代之的是获取URL url = rule.rule。知道为什么您的方法对我不起作用吗?
J-bob 2012年

@ J-bob-与之相关的路由很可能DeleteEvent具有必需的参数-您可以对此进行特殊说明,也可以在其中过滤掉任何规则len(rule.arguments) > len(rule.defaults)
Sean Vieira 2012年

哦,我想我明白了。url_for没有参数就无法为该方法生成URL,对吗?可以,但是无论如何我的方法似乎都能正常工作,如果将URL作为参数,它将保留该部分。谢谢!
J-bob 2012年

1
这是一个很好的开始。关于如何创建一个完整的基于烧瓶的自我文档化Web服务的任何建议,其中列出了所有参数(例如?spam =“ eggs”)?也许可以从实现方法的文档字符串中提取此信息。
列昂尼德2014年

2
最好不要url_for(rule.endpoint)使用rule.rule,因为这可以解决同一方法具有多个路径的情况。
Zini 2015年

82

我刚刚遇到了同样的问题。上面的解决方案太复杂了。只需在您的项目下打开一个新的shell:

    python
    >>> from app import app
    >>> app.url_map

第一个“ app ”是我的项目脚本:app.py,另一个是我的网站名称。

(此解决方案适用于路由很少的小型网络)


1
这可能无法直接回答问题。但是它当然值得更多的赞扬。
UltraInstinct

该答案非常适合不需要您向应用程序中添加任何代码的情况。我用它在几秒钟内获得了想要的答案,而无需重建代码。
joshdick

“有没有办法获取我的应用中已声明的所有路线的列表?” 我认为这直接回答了问题,应该是公认的答案。太简单。谢谢。
andho '18

2
我真的看不出这比接受的答案更简单或更清晰。它建议采用相同的方法,但是要花很长时间才能达到目的,并且没有显示如何遍历Map实例或访问实例所Rule包含的任何属性,否则,您将无法做任何有用的事情。
Mark Amery

57

我在我的帮助方法manage.py

@manager.command
def list_routes():
    import urllib
    output = []
    for rule in app.url_map.iter_rules():

        options = {}
        for arg in rule.arguments:
            options[arg] = "[{0}]".format(arg)

        methods = ','.join(rule.methods)
        url = url_for(rule.endpoint, **options)
        line = urllib.unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, url))
        output.append(line)

    for line in sorted(output):
        print line

它通过构建一组虚拟选项来解决缺少的参数。输出如下:

CampaignView:edit              HEAD,OPTIONS,GET     /account/[account_id]/campaigns/[campaign_id]/edit
CampaignView:get               HEAD,OPTIONS,GET     /account/[account_id]/campaign/[campaign_id]
CampaignView:new               HEAD,OPTIONS,GET     /account/[account_id]/new

然后运行它:

python manage.py list_routes

有关manage.py结帐的更多信息,请访问:http : //flask-script.readthedocs.org/en/latest/


5
以上效果很好。只需更改urllib.unquoteurllib.parse.unquoteand print line即可print(line),它也适用于python3.x。
刮刀2013年

1
这不适用于非字符串参数,我建议改用John Jiang的答案。
nico

42

与乔纳森(Jonathan)的回答类似,我选择这样做。我看不到使用url_for的意义,因为如果您的参数不是字符串(例如float),它将中断

@manager.command
def list_routes():
    import urllib

    output = []
    for rule in app.url_map.iter_rules():
        methods = ','.join(rule.methods)
        line = urllib.unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, rule))
        output.append(line)

    for line in sorted(output):
        print(line)

31

显然,从版本0.11开始,Flask具有内置的CLI。内置命令之一列出了路由:

FLASK_APP='my_project.app' flask routes

这绝对是太棒了!
pfabri

1
flask urls对我来说(0.12.1)。看到了,flask --help但是在CLI页面
上看

路线似乎已在烧瓶1.1.2中删除
Jerry Ji

5

由于您没有指定必须在命令行运行,因此可以在json中为仪表板或其他非命令行界面轻松返回以下内容。无论如何,从设计的角度来看,结果和输出确实不应该混在一起。即使是很小的程序,它也是不好的程序设计。然后,可以在Web应用程序,命令行或其他任何提取json的内容中使用以下结果。

您也没有指定您需要了解与每个路由关联的python函数,因此这可以更准确地回答您的原始问题。

我在下面使用自己将输出添加到监视仪表板。如果您想要可用的路由方法(GET,POST,PUT等),则需要将其与上述其他答案结合使用。

Rule的repr()负责在路由中转换所需的参数。

def list_routes():
    routes = []

    for rule in app.url_map.iter_rules():
        routes.append('%s' % rule)

    return routes

使用列表推导的同一件事:

def list_routes():
    return ['%s' % rule for rule in app.url_map.iter_rules()]

样本输出:

{
  "routes": [
    "/endpoint1", 
    "/nested/service/endpoint2", 
    "/favicon.ico", 
    "/static/<path:filename>"
  ]
}

2

如果您需要自己访问视图函数app.url_map,请使用代替app.view_functions

示例脚本:

from flask import Flask

app = Flask(__name__)

@app.route('/foo/bar')
def route1():
    pass

@app.route('/qux/baz')
def route2():
    pass

for name, func in app.view_functions.items():
    print(name)
    print(func)
    print()

运行上面脚本的输出:

static
<bound method _PackageBoundObject.send_static_file of <Flask '__main__'>>

route1
<function route1 at 0x128f1b9d8>

route2
<function route2 at 0x128f1ba60>

(请注意,包含了“静态”路线,该路线由Flask自动创建。)


2

在导出或设置FLASK_APP环境变量后,可以通过运行以下命令来查看所有通过Flask Shell的路由。 flask shell app.url_map


1

在烧瓶应用程序中执行以下操作:

flask shell
>>> app.url_map
Map([<Rule '/' (OPTIONS, HEAD, GET) -> helloworld>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.