Получить список всех маршрутов, определенных в приложении Flask

У меня есть сложное веб-приложение на основе Flask. Есть много отдельных файлов с функциями просмотра. Их URL-адреса определены с @app.route('/...') декоратор. Есть ли способ получить список всех маршрутов, которые были объявлены в моем приложении? Возможно, есть какой-то метод, который я могу вызвать на app объект?

12 ответов

Решение

Все маршруты для приложения хранятся на 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

См. Отображение ссылок на новые веб-страницы, созданные для получения дополнительной информации.

Я только что встретил тот же вопрос. Эти решения выше слишком сложны. Просто откройте новую оболочку под ваш проект:

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

Первое "приложение" - это сценарий моего проекта: app.py, другое - имя моей сети.

(это решение для паутины с небольшим маршрутом)

Я делаю вспомогательный метод на моем 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/

По-видимому, начиная с версии 0.11, Flask имеет встроенный интерфейс командной строки. Одна из встроенных команд перечисляет маршруты:

FLASK_APP='my_project.app' flask routes

Подобно ответу Джонатана, я решил сделать это вместо этого. Я не вижу смысла использовать 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)

Используйте команду cli в каталоге, где находится ваш проект фляги.

      flask routes

Поскольку вы не указали, что он должен запускаться из командной строки, в json можно легко вернуть следующую информацию для панели мониторинга или другого интерфейса без командной строки. Результат и результат на самом деле не должны смешиваться с точки зрения дизайна. Это плохой дизайн программы, даже если это крошечная программа. Результат, приведенный ниже, можно затем использовать в веб-приложении, командной строке или в любом другом объекте, в котором используется json.

Вы также не указали, что вам нужно знать функцию python, связанную с каждым маршрутом, так что это более точно отвечает на ваш первоначальный вопрос.

Я использую ниже, чтобы добавить вывод на панель мониторинга самостоятельно. Если вы хотите использовать доступные методы маршрута (GET, POST, PUT и т. Д.), Вам нужно будет объединить их с другими ответами выше.

Правило 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>"
  ]
}

Если вам нужен доступ к самим функциям просмотра, то вместо 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.)

Вы можете просмотреть все маршруты через оболочку flask, выполнив следующие команды после экспорта или установки переменной среды FLASK_APP. flask shell app.url_map

Внутри вашего фляжного приложения выполните:

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

То есть, если имя вашего приложения Flask — «приложение».

Это атрибут экземпляра приложения Flask.

См. https://flask.palletsprojects.com/en/2.1.x/api/#flask.Flask.url_map

У колбы есть какой-то классный фрагмент, есть один для:

http://flask.pocoo.org/snippets/117/

@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
Другие вопросы по тегам