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

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

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

I have a complex Flask-based web app. There are lots of separate files with view functions. Their URLs are defined with the @app.route('/...') decorator. Is there a way to get a list of all the routes that have been declared throughout my app? Perhaps there is some method I can call on the app object?


回答 0

应用程序的所有路由都存储在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

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

All the routes for an application are stored on app.url_map which is an instance of werkzeug.routing.Map. You can iterate over the Rule instances by using the iter_rules method:

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

See Display links to new webpages created for a bit more information.


回答 1

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

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

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

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

I just met the same question. Those solution above is too complex. Just open a new shell under your project:

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

The first ‘app‘ is my project script: app.py, another is my web’s name.

(this solution is for tiny web with a little route)


回答 2

我在我的帮助方法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/

I make a helper method on my 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

It solves the the missing argument by building a dummy set of options. The output looks like:

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

Then to run it:

python manage.py list_routes

For more on manage.py checkout: http://flask-script.readthedocs.org/en/latest/


回答 3

与乔纳森(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)

Similar to Jonathan’s answer I opted to do this instead. I don’t see the point of using url_for as it will break if your arguments are not string e.g. 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)

回答 4

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

FLASK_APP='my_project.app' flask routes

Apparently, since version 0.11, Flask has a built-in CLI. One of the built-in commands lists the routes:

FLASK_APP='my_project.app' flask routes

回答 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>"
  ]
}

Since you did not specify that it has to be run command-line, the following could easily be returned in json for a dashboard or other non-command-line interface. The result and the output really shouldn’t be commingled from a design perspective anyhow. It’s bad program design, even if it is a tiny program. The result below could then be used in a web application, command-line, or anything else that ingests json.

You also didn’t specify that you needed to know the python function associated with each route, so this more precisely answers your original question.

I use below to add the output to a monitoring dashboard myself. If you want the available route methods (GET, POST, PUT, etc.), you would need to combine it with other answers above.

Rule’s repr() takes care of converting the required arguments in the route.

def list_routes():
    routes = []

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

    return routes

The same thing using a list comprehension:

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

Sample output:

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

回答 6

如果您需要自己访问视图函数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自动创建。)

If you need to access the view functions themselves, then instead of app.url_map, use app.view_functions.

Example script:

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()

Output from running the script above:

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

route1
<function route1 at 0x128f1b9d8>

route2
<function route2 at 0x128f1ba60>

(Note the inclusion of the “static” route, which is created automatically by Flask.)


回答 7

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

You can view all the Routes via flask shell by running the following commands after exporting or setting FLASK_APP environment variable. flask shell app.url_map


回答 8

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

flask shell
>>> app.url_map
Map([<Rule '/' (OPTIONS, HEAD, GET) -> helloworld>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])

inside your flask app do:

flask shell
>>> app.url_map
Map([<Rule '/' (OPTIONS, HEAD, GET) -> helloworld>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])