Dapatkan daftar semua rute yang ditentukan dalam aplikasi Flask


145

Saya memiliki aplikasi web berbasis Flask yang kompleks. Ada banyak file terpisah dengan fungsi tampilan. URL mereka didefinisikan dengan @app.route('/...')dekorator. Apakah ada cara untuk mendapatkan daftar semua rute yang telah dinyatakan di seluruh aplikasi saya? Mungkin ada beberapa metode yang bisa saya panggil pada appobjek?

Jawaban:


152

Semua rute untuk aplikasi disimpan di app.url_mapmana merupakan instance dari werkzeug.routing.Map. Anda dapat mengulangi Ruleinstance dengan menggunakan iter_rulesmetode:

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

Lihat Menampilkan tautan ke halaman web baru yang dibuat untuk informasi lebih lanjut.


Manis! Kecuali saya punya masalah dengan garis url = url_for(rule.endpoint). Saya baru saja mendapat kesalahan ini BuildError: ('DeleteEvent', {}, None). Sebagai gantinya, untuk mendapatkan url yang baru saja saya lakukan url = rule.rule. Adakah alasan mengapa metode Anda tidak berhasil untuk saya?
J-bob

@ J-bob - kemungkinan besar rute yang terkait dengan DeleteEventmemiliki parameter yang diperlukan - Anda dapat menggunakan huruf khusus untuk itu atau menyaring aturan apa pun di manalen(rule.arguments) > len(rule.defaults)
Sean Vieira

Oh saya rasa saya mengerti. url_fortidak dapat menghasilkan URL untuk methid itu tanpa parameter, kan? OK, tapi sepertinya metode saya tetap bekerja, itu hanya menjaga bagian itu jika URL sebagai parameter. Terima kasih!
J-bob

1
Ini adalah awal yang baik. Adakah saran untuk cara membuat layanan web berbasis labu yang sepenuhnya terdokumentasi sendiri, di mana semua parameter (seperti? Spam = "telur") terdaftar? Mungkin info ini dapat diekstraksi dari dokumentasi metode implementasi.
Leonid

2
Daripada menggunakan url_for(rule.endpoint)penggunaan rule.ruleyang jauh lebih baik karena memecahkan kasus di mana Anda memiliki lebih dari satu rute untuk metode yang sama.
Zini

82

Saya baru saja bertemu pertanyaan yang sama. Solusi di atas terlalu kompleks. Cukup buka shell baru di bawah proyek Anda:

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

' Aplikasi ' pertama adalah skrip proyek saya: app.py , yang lain adalah nama web saya.

(solusi ini untuk web kecil dengan rute kecil)


1
Ini mungkin tidak menjawab pertanyaan secara langsung. Tapi itu tentu layak mendapat lebih banyak upvotes.
UltraInstinct

Jawaban ini bagus untuk tidak mengharuskan Anda menambahkan kode apa pun ke aplikasi Anda. Saya menggunakannya untuk mendapatkan jawaban yang saya inginkan dalam hitungan detik tanpa membangun kembali kode saya.
joshdick

"Apakah ada cara untuk mendapatkan daftar semua rute yang telah dinyatakan di seluruh aplikasi saya?" Saya pikir ini menjawab pertanyaan secara langsung dan harus menjadi jawaban yang diterima. Begitu mudah. Terima kasih.
andho

2
Saya tidak benar-benar melihat bagaimana ini lebih sederhana atau lebih jelas daripada jawaban yang diterima. Ini menyarankan pendekatan yang sama, tetapi membutuhkan waktu lebih lama untuk sampai ke titik dan tidak menunjukkan bagaimana untuk mengulangi Mapcontoh atau mengakses salah satu properti Ruledi dalamnya, yang tanpanya Anda tidak dapat benar-benar melakukan sesuatu yang bermanfaat.
Mark Amery

57

Saya membuat metode pembantu pada 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

Ini memecahkan argumen yang hilang dengan membangun serangkaian opsi boneka. Outputnya terlihat seperti:

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

Kemudian untuk menjalankannya:

python manage.py list_routes

Untuk lebih lanjut tentang checkout manage.py: http://flask-script.readthedocs.org/en/latest/


5
Di atas bekerja dengan sangat baik. Ubah saja urllib.unquoteke urllib.parse.unquotedan print lineke print(line)dan itu bekerja di python 3.x juga.
squeegee

1
Ini tidak berfungsi untuk argumen non-string, saya sarankan untuk menggunakan jawaban John Jiang sebagai gantinya.
nico

42

Mirip dengan jawaban Jonathan saya memilih untuk melakukan ini sebagai gantinya. Saya tidak melihat gunanya menggunakan url_for karena akan rusak jika argumen Anda bukan string misalnya 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

Rupanya, sejak versi 0.11, Flask memiliki CLI bawaan . Salah satu perintah bawaan mencantumkan rute:

FLASK_APP='my_project.app' flask routes

Ini benar-benar brilian!
pfabri

1
flask urlsuntuk saya (0.12.1). Melihat itu flask --helptetapi saya tidak melihat rute atau url pada halaman CLI
mrgnw

rute tampaknya dihapus dalam labu 1.1.2
Jerry Ji

5

Karena Anda tidak menentukan bahwa itu harus dijalankan command-line, berikut ini dapat dengan mudah dikembalikan di json untuk dasbor atau antarmuka non-command-line lainnya. Bagaimanapun juga, hasil dan keluarannya seharusnya tidak disatukan dari perspektif desain. Ini desain program yang buruk, bahkan jika itu adalah program kecil. Hasil di bawah ini kemudian dapat digunakan dalam aplikasi web, command-line, atau apa pun yang menelan json.

Anda juga tidak menentukan bahwa Anda perlu mengetahui fungsi python yang terkait dengan setiap rute, jadi ini lebih tepat menjawab pertanyaan awal Anda.

Saya menggunakan di bawah ini untuk menambahkan output ke dashboard pemantauan sendiri. Jika Anda ingin metode rute yang tersedia (DAPATKAN, POST, PUT, dll.), Anda harus menggabungkannya dengan jawaban lain di atas.

Repr () aturan mengatur konversi argumen yang diperlukan dalam rute.

def list_routes():
    routes = []

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

    return routes

Hal yang sama menggunakan pemahaman daftar:

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

Output sampel:

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

2

Jika Anda perlu mengakses fungsi tampilan itu sendiri, maka alih-alih app.url_map, gunakan app.view_functions.

Skrip contoh:

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 dari menjalankan skrip di atas:

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

route1
<function route1 at 0x128f1b9d8>

route2
<function route2 at 0x128f1ba60>

(Perhatikan penyertaan rute "statis", yang dibuat secara otomatis oleh Flask.)


2

Anda dapat melihat semua Rute melalui flask shell dengan menjalankan perintah berikut setelah mengekspor atau mengatur variabel lingkungan FLASK_APP. flask shell app.url_map


1

di dalam aplikasi labu Anda lakukan:

flask shell
>>> app.url_map
Map([<Rule '/' (OPTIONS, HEAD, GET) -> helloworld>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.