Ottieni l'elenco di tutti i percorsi definiti nell'app Flask


145

Ho una complessa app web basata su Flask. Esistono molti file separati con funzioni di visualizzazione. I loro URL sono definiti con il @app.route('/...')decoratore. C'è un modo per ottenere un elenco di tutti i percorsi che sono stati dichiarati in tutta la mia app? Forse esiste un metodo che posso chiamare appsull'oggetto?

Risposte:


152

Tutti i percorsi per un'applicazione sono memorizzati su app.url_mapcui è presente un'istanza di werkzeug.routing.Map. È possibile scorrere le Ruleistanze utilizzando il iter_rulesmetodo:

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

Vedere Visualizzare collegamenti a nuove pagine Web create per ulteriori informazioni.


Dolce! Tranne che ho avuto un problema con la linea url = url_for(rule.endpoint). Ho appena ricevuto questo errore BuildError: ('DeleteEvent', {}, None). Invece, per ottenere l'URL ho appena fatto url = rule.rule. Hai idea del perché il tuo metodo non funziona per me?
— J-bob,

@ J-bob - molto probabilmente il percorso associato DeleteEventha un parametro richiesto - puoi sia quello speciale che uno o filtrare eventuali regole in cuilen(rule.arguments) > len(rule.defaults)
— Sean Vieira

Oh penso di averlo capito. url_fornon puoi generare l'URL per quel methid senza un parametro, giusto? OK, ma sembra che il mio metodo funzioni comunque, mantiene solo quella parte se l'URL come parametro. Grazie!
— J-bob,

1
Questo è un ottimo inizio. Qualche suggerimento su come creare un servizio web basato su matraccio completamente auto-documentante, in cui sono elencati tutti i parametri (come? Spam = "uova")? Forse queste informazioni possono essere estratte da una documentazione di un metodo di implementazione.
— Leonid,

2
Invece di usare l' url_for(rule.endpoint)uso rule.ruleè molto meglio perché risolvere i casi in cui hai più di un percorso per lo stesso metodo.
— Zini,

84

Ho appena incontrato la stessa domanda. Quella soluzione sopra è troppo complessa. Basta aprire una nuova shell sotto il tuo progetto:

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

La prima ' app ' è lo script del mio progetto: app.py , un altro è il nome del mio web.

(questa soluzione è per la piccola rete con un piccolo itinerario)


1
Questo probabilmente non risponde direttamente alla domanda. Ma sicuramente merita molti più voti.
— UltraInstinct

Questa risposta è ottima per non aver bisogno di aggiungere alcun codice alla tua applicazione. L'ho usato per ottenere la risposta che volevo in pochi secondi senza ricostruire il mio codice.
— joshdick,

"C'è un modo per ottenere un elenco di tutti i percorsi che sono stati dichiarati in tutta la mia app?" Penso che questo risponda direttamente alla domanda e dovrebbe essere la risposta accettata. Così facile. Grazie.
— andho

2
Non vedo davvero come questo sia più semplice o più chiaro della risposta accettata. Sta suggerendo lo stesso approccio, ma richiede più tempo per arrivare al punto e non mostra come iterare sull'istanza Mapo accedere a nessuna delle proprietà della Rules che contiene, senza la quale non si può effettivamente fare nulla di utile.
— Mark Amery,

57

Faccio un metodo di supporto sul mio 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

Risolve l'argomento mancante costruendo una serie fittizia di opzioni. L'output è simile a:

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

Quindi eseguirlo:

python manage.py list_routes

Per ulteriori informazioni sul checkout manage.py: http://flask-script.readthedocs.org/en/latest/


5
Quanto sopra funziona molto bene. Basta passare urllib.unquotea urllib.parse.unquotee print linea print(line)e funziona anche in Python 3.x.
— tergipavimento

1
Questo non funziona per argomenti senza stringhe, consiglio invece di usare la risposta di John Jiang.
— nico,

42

Simile alla risposta di Jonathan, invece, ho deciso di farlo. Non vedo il punto di usare url_for poiché si romperà se i tuoi argomenti non sono stringhe, ad esempio 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)

32

Apparentemente, dalla versione 0.11, Flask ha una CLI integrata . Uno dei comandi integrati elenca i percorsi:

FLASK_APP='my_project.app' flask routes

Questo è assolutamente geniale!
— pfabri

1
flask urlsper me (0.12.1). L' flask --helpho visto ma non vedo i percorsi o gli URL nella pagina della CLI
— mrgnw

le rotte sembrano essere rimosse nel pallone 1.1.2
— Jerry Ji l'

5

Poiché non è stato specificato che deve essere eseguito dalla riga di comando, è possibile che in Json venga facilmente restituito un dashboard o un'altra interfaccia non da riga di comando. In ogni caso, il risultato e l'output non dovrebbero essere mescolati dal punto di vista del design. È una cattiva progettazione del programma, anche se è un programma minuscolo. Il risultato che segue potrebbe quindi essere utilizzato in un'applicazione Web, nella riga di comando o in qualsiasi altra cosa che ingerisca json.

Inoltre, non hai specificato che dovevi conoscere la funzione Python associata a ciascuna rotta, quindi questo risponde più precisamente alla tua domanda originale.

Uso di seguito per aggiungere personalmente l'output a una dashboard di monitoraggio. Se desideri i metodi di percorso disponibili (GET, POST, PUT, ecc.), Dovrai combinarlo con altre risposte sopra.

Il repr () di Rule si occupa di convertire gli argomenti richiesti nella rotta.

def list_routes():
    routes = []

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

    return routes

La stessa cosa usando una comprensione della lista:

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

Uscita campione:

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

2

Se è necessario accedere alle funzioni di visualizzazione stesse app.url_map, utilizzare inveceapp.view_functions .

Script di esempio:

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 dall'esecuzione dello script sopra:

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

route1
<function route1 at 0x128f1b9d8>

route2
<function route2 at 0x128f1ba60>

(Notare l'inclusione della route "statica", che viene creata automaticamente da Flask.)


2

È possibile visualizzare tutte le rotte tramite shell boccetta eseguendo i seguenti comandi dopo aver esportato o impostato la variabile di ambiente FLASK_APP. flask shell app.url_map


1

nell'app della beuta fai:

flask shell
>>> app.url_map
Map([<Rule '/' (OPTIONS, HEAD, GET) -> helloworld>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.