У меня сложное веб-приложение на основе флаков. Существует множество отдельных файлов с функциями просмотра. Их URL-адреса определяются с помощью декоратора @app.route('/...')
. Есть ли способ получить список всех маршрутов, которые были объявлены в моем приложении? Возможно, есть какой-то метод, который я могу вызвать для объекта app
?
Получить список всех маршрутов, определенных в приложении Flask
Ответ 1
Все маршруты для приложения хранятся на 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
Смотрите Показать ссылки на новые созданные веб-страницы для получения дополнительной информации.
Ответ 2
Я только что встретил тот же вопрос. Это решение слишком сложно. Просто откройте новую оболочку под своим проектом:
python
>>> from app import app
>>> app.url_map
Первым "приложением" является мой проект script: app.py, другой - мое имя в сети.
(это решение для жестяной сети с небольшим маршрутом)
Ответ 3
Я делаю вспомогательный метод на моем 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/
Ответ 4
Как и Джонатан, я решил сделать это вместо этого. Я не вижу смысла использовать url_for, поскольку он сломается, если ваши аргументы не являются строками, например. Поплавок
@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)
Ответ 5
По-видимому, начиная с версии 0.11, Flask имеет встроенный интерфейс командной строки. Одна из встроенных команд перечисляет маршруты:
FLASK_APP='my_project.app' flask routes
Ответ 6
Поскольку вы не указали, что он должен быть запущен в командной строке, в json можно легко вернуть следующую информацию для панели управления или другого интерфейса без командной строки. Результат и результат действительно не должны смешиваться с проектной перспективой. Это плохой дизайн программы, даже если это крошечная программа. Результат ниже можно было бы использовать в веб-приложении, командной строке или что-нибудь еще, что поглощает 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>"
]
}
Ответ 7
Если вам нужно получить доступ к функциям представления, то вместо 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.)
Ответ 8
Вы можете просмотреть все маршруты через оболочку фляги, выполнив следующие команды после экспорта или установки переменной среды FLASK_APP. flask shell app.url_map
Ответ 9
Flask имеет классный фрагмент, есть один для:
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