Flask uygulamasında tanımlanan tüm rotaların listesini alın


145

Flask tabanlı karmaşık bir web uygulamam var. Görüntüleme işlevlerine sahip birçok ayrı dosya vardır. URL'leri @app.route('/...')dekoratörle tanımlanır . Uygulamam boyunca bildirilen tüm rotaların bir listesini almanın bir yolu var mı? Belki de appnesne üzerinde çağırabileceğim bir yöntem var mı?

Yanıtlar:


152

Bir uygulamanın tüm yolları, üzerinde app.url_mapbir örnek olarak saklanır werkzeug.routing.Map. Sen adımlayabilirsiniz Rulekullanarak örnekleri iter_rulesyöntemi:

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

Biraz daha fazla bilgi için Oluşturulan yeni web sayfalarına bağlantıları görüntüleme başlıklı makaleye bakın .


Tatlı! Ancak hatla ilgili bir sorunum vardı url = url_for(rule.endpoint). Bu hatayı aldım BuildError: ('DeleteEvent', {}, None). Bunun yerine, az önce yaptığım url'yi almak için url = rule.rule. Yöntemin neden işe yaramadığı hakkında bir fikrin var mı?
J-bob

B J-bob - muhtemelen ilişkili yol DeleteEventbir sahiptir gerekli parametre - Eğer ya özel durum, herhangi bir kural üzerinden bir ya da filtrelen(rule.arguments) > len(rule.defaults)
Sean Vieira

Sanırım anladım. url_forparametresiz o methid için URL üretemezsiniz, değil mi? Tamam, ama benim yöntem zaten çalışıyor gibi görünüyor, URL parametre olarak sadece bu kısmı tutar. Teşekkürler!
J-bob

1
Bu harika bir başlangıç. Tüm parametrelerin (? Spam = "yumurta" gibi) listelendiği, tamamen kendi kendini belgeleyen bir şişeye dayalı web hizmetinin nasıl oluşturulacağına dair herhangi bir öneriniz var mı? Belki de bu bilgi, bir uygulama yönteminin öğretisinden elde edilebilir.
Leonid

2
Kullanım yerine bu çok daha iyi beacause url_for(rule.endpoint)kullanmak rule.ruleaynı yöntem için birden fazla rota olduğu durumlarda çözmek.
Zini

84

Ben sadece aynı soru ile tanıştım. Yukarıdaki çözüm çok karmaşık. Projenizin altında yeni bir kabuk açın:

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

İlk ' uygulama ' benim proje betiğim : app.py , bir diğeri adı.

(bu çözüm küçük bir rota içeren küçük web içindir)


1
Bu muhtemelen soruya doğrudan cevap vermez. Ama elbette çok daha fazla oyu hak ediyor.
UltraInstinct

Bu yanıt, uygulamanıza kod eklemenizi gerektirmemesi için mükemmeldir. Kodumu yeniden oluşturmadan saniyeler içinde istediğim cevabı almak için kullandım.
joshdick

"Uygulamam boyunca bildirilen tüm rotaların bir listesini almanın bir yolu var mı?" Bence bu doğrudan soruyu cevaplıyor ve kabul edilen cevap olmalı. Çok kolay. Teşekkürler.
andho

2
Bunun kabul edilen cevaptan daha basit veya daha net olduğunu gerçekten görmüyorum. Aynı yaklaşımı öneriyor, ancak konuya ulaşmak daha uzun sürüyor ve Mapörnek üzerinde yineleme yapmayı veya Ruleiçerdiği özelliklerin herhangi birine erişmeyi göstermiyor , bu olmadan gerçekten yararlı bir şey yapamazsınız.
Mark Amery

57

Ben yardımcı bir yöntem yapmak benim 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

Eksik argümanı kukla bir seçenekler kümesi oluşturarak çözer. Çıktı şöyle görünür:

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

Sonra çalıştırmak için:

python manage.py list_routes

Manage.py checkout hakkında daha fazla bilgi için: http://flask-script.readthedocs.org/en/latest/


5
Yukarıdaki çok iyi çalışıyor. Sadece değiştirmek urllib.unquoteiçin urllib.parse.unquoteve print lineiçin print(line)ve hem de piton 3.x çalışır.
Çekçek

1
Bu, string olmayan argümanlar için işe yaramaz, bunun yerine John Jiang'ın cevabını kullanmanızı öneririm.
nico

42

Jonathan'ın cevabına benzer şekilde ben de bunu yapmayı tercih ettim. Eğer argümanlar dize örneğin float değilse kırılacağı gibi url_for kullanma noktasını görmüyorum

@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

Komut satırı çalıştırılması gerektiğini belirtmediğiniz için, aşağıdakiler bir pano veya diğer komut satırı olmayan arayüz için json'da kolayca döndürülebilir. Sonuç ve çıktı gerçekten bir tasarım perspektifinden karıştırılmamalıdır. Küçük bir program olsa bile kötü program tasarımı. Aşağıdaki sonuç daha sonra bir web uygulamasında, komut satırında veya json'u yutan başka bir şeyde kullanılabilir.

Ayrıca, her bir rota ile ilişkili python işlevini bilmeniz gerektiğini belirtmediniz, bu da orijinal sorunuzu daha kesin olarak cevaplar.

Çıkışı izleme panosuna kendim eklemek için aşağıda kullanıyorum. Mevcut rota yöntemlerini (GET, POST, PUT, vb.) İstiyorsanız, yukarıdaki diğer cevaplarla birleştirmeniz gerekir.

Kuralın repr () yöntemi, rotadaki gerekli bağımsız değişkenleri dönüştürmeye özen gösterir.

def list_routes():
    routes = []

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

    return routes

Liste kavrayışı kullanan aynı şey:

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

Örnek çıktı:

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

2

Görünüm işlevlerine erişmeniz gerekiyorsa, yerine app.url_mapkullanın app.view_functions.

Örnek komut dosyası:

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

Yukarıdaki komut dosyasını çalıştırma çıktısı:

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

route1
<function route1 at 0x128f1b9d8>

route2
<function route2 at 0x128f1ba60>

(Flask tarafından otomatik olarak oluşturulan "statik" yolun dahil edildiğine dikkat edin.)


2

FLASK_APP ortam değişkenini dışa aktardıktan veya ayarladıktan sonra aşağıdaki komutları çalıştırarak tüm Rotaları flask kabuğu aracılığıyla görüntüleyebilirsiniz. flask shell app.url_map


1

flask uygulamanızın içinde şunları yapın:

flask shell
>>> app.url_map
Map([<Rule '/' (OPTIONS, HEAD, GET) -> helloworld>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.