Flaskアプリで定義されたすべてのルートのリストを取得します


145

Flaskベースの複雑なWebアプリがあります。ビュー機能を備えた個別のファイルがたくさんあります。それらのURLは@app.route('/...')デコレーターで定義されます。アプリ全体で宣言されているすべてのルートのリストを取得する方法はありますか?おそらく、appオブジェクトで呼び出すことができるいくつかのメソッドがありますか?

回答:


152

app.url_mapインスタンスであるアプリケーションのすべてのルートが格納されますwerkzeug.routing.Map。次Ruleiter_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

詳細については、作成された新しいWebページへのリンクの表示を参照してください。


甘い!私が回線に問題があったことを除いてurl = url_for(rule.endpoint)。このエラーが発生しましたBuildError: ('DeleteEvent', {}, None)。代わりに、先ほど行ったURLを取得しurl = rule.ruleます。あなたの方法が私にとってうまくいかない理由はありますか?
J-bob

@ J-bob-ほとんどの場合、関連付けられたルートにDeleteEvent必須パラメーターがあります-特殊なケースを使用するか、ルールを除外することができますlen(rule.arguments) > len(rule.defaults)
Sean Vieira

わかった。url_forパラメータなしでそのmethidのURLを生成することはできませんよね?わかりましたが、私の方法はとにかく機能するように見えますが、URLをパラメーターとして使用している場合は、その部分だけが保持されます。ありがとう!
J-bob

1
これは素晴らしいスタートです。すべてのパラメーター(?spam = "eggs"など)がリストされている、完全に自己文書化するフラスコベースのWebサービスを作成する方法についての提案はありますか?おそらく、この情報は実装メソッドのdocstringから抽出できます。
レオニード

2
同じメソッドに複数のルートがあるケースを解決するため、useを使用url_for(rule.endpoint)するrule.ruleよりもはるかに優れています。
Zini、2015

82

私は同じ質問に会いました。上記のソリューションは複雑すぎます。プロジェクトの下で新しいシェルを開くだけです:

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

最初の「app」は私のプロジェクトスクリプトであるapp.pyで、もう1つは私のウェブの名前です。

(この解決策は、ルートが少ない小さなWeb用です)


1
これはおそらく質問に直接答えることはありません。しかし、それはもっと多くの賛成に値するに違いありません。
UltraInstinct 2017年

この回答は、アプリケーションにコードを追加する必要がない場合に最適です。私はそれを使用して、コードを再構築せずにほんの数秒で必要な答えを得ました。
ジョシュディック2018

「アプリ全体で宣言されているすべてのルートのリストを取得する方法はありますか?」これは質問に直接答えるので、受け入れられるべき答えだと思います。とても簡単。ありがとう。
andho 2018

2
これが受け入れられた回答よりも単純で明確であるかどうかは、実際にはわかりません。同じアプローチを提案していますが、ポイントに到達するまでに時間がかかり、Mapインスタンスを反復したり、インスタンスRuleに含まれるのプロパティにアクセスしたりする方法は示されていないため、実際には何も実行できません。
マークアメリー2018年

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.unquoteしてprint lineまでprint(line)、それがうまくとしてPython 3.xの中で動作します。
スキージ2013年

1
これは文字列以外の引数では機能しません。代わりにJohn Jiangの回答を使用することをお勧めします。
nico

42

ジョナサンの答えと同様に、私は代わりにこれを行うことを選びました。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があります。組み込みコマンドの1つはルートをリストします:

FLASK_APP='my_project.app' flask routes

これは絶対に素晴らしいです!
pfabri

1
flask urls私にとって(0.12.1)。それを見たflask --helpが、CLIページにルートまたはURLが表示されない
mrgnw

ルートはフラスコ1.1.2で削除されたようです
ジェリー・ジ

5

コマンドラインで実行する必要があることを指定しなかったため、ダッシュボードまたはその他の非コマンドラインインターフェースの場合、jsonで以下を簡単に返すことができます。いずれにしても、結果と出力は、設計の観点から実際に混同すべきではありません。たとえそれが小さなプログラムであっても、それは悪いプログラム設計です。以下の結果は、Webアプリケーション、コマンドライン、または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>"
  ]
}

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 app.url_map


1

あなたのフラスコアプリの中で:

flask shell
>>> app.url_map
Map([<Rule '/' (OPTIONS, HEAD, GET) -> helloworld>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.