web-dev-qa-db-fra.com

Obtenir la liste de toutes les routes définies dans l'application Flask

J'ai une application Web complexe basée sur Flask. Il y a beaucoup de fichiers séparés avec des fonctions d'affichage. Leurs URL sont définies avec le décorateur @app.route('/...'). Existe-t-il un moyen d’obtenir une liste de toutes les routes déclarées dans l’application? Peut-être y a-t-il une méthode que je peux appeler sur l'objet app?

117
J-bob

Toutes les routes d’une application sont stockées sur app.url_map qui est une instance de werkzeug.routing.Map . Vous pouvez parcourir les instances Rule à l’aide de iter_rules méthode:

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

Voir Afficher les liens vers les nouvelles pages Web créées pour un peu plus d'informations.

126
Sean Vieira

Je viens de rencontrer la même question. La solution ci-dessus est trop complexe. Ouvrez simplement un nouveau Shell dans le cadre de votre projet:

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

Le premier 'app' est mon script de projet: app.py, un autre est le nom de mon site Web.

(cette solution est pour le web avec un petit itinéraire)

60
Vi.Ci

Je fais une méthode d'assistance sur mon 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

Il résout l'argument manquant en construisant un ensemble d'options factices. La sortie ressemble à:

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

Puis pour le lancer:

python manage.py list_routes

Pour plus d'informations sur manage.py checkout: http://flask-script.readthedocs.org/en/latest/

53
Jonathan

Semblable à la réponse de Jonathan, j'ai choisi de le faire à la place. Je ne vois pas l'intérêt d'utiliser url_for car cela casserait si vos arguments ne sont pas des chaînes, par exemple. flotte

@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)
40
John Jiang

Apparemment, depuis la version 0.11, Flask a une CLI intégrée . Une des commandes intégrées répertorie les itinéraires:

FLASK_APP='my_project.app' flask routes
14
theY4Kman

Etant donné que vous n'avez pas spécifié qu'il doit être exécuté en ligne de commande, les éléments suivants pourraient facilement être renvoyés dans json pour un tableau de bord ou une autre interface autre qu'en ligne de commande. De toute façon, le résultat et la sortie ne doivent en aucun cas être mélangés. C'est une mauvaise conception de programme, même s'il s'agit d'un programme minuscule. Le résultat ci-dessous peut ensuite être utilisé dans une application Web, une ligne de commande ou tout autre élément intégrant JSON.

Vous n'avez pas non plus précisé que vous deviez connaître la fonction python associée à chaque route), ce qui répond donc plus précisément à votre question initiale.

J'utilise ci-dessous pour ajouter moi-même la sortie à un tableau de bord de surveillance. Si vous souhaitez connaître les méthodes de routage disponibles (GET, POST, PUT, etc.), vous devrez les combiner avec les autres réponses ci-dessus.

La règle repr () se charge de convertir les arguments requis dans la route.

def list_routes():
    routes = []

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

    return routes

La même chose en utilisant une compréhension de liste:

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

Exemple de sortie:

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

Si vous avez besoin d'accéder aux fonctions de vue elles-mêmes, alors au lieu de app.url_map, utilisation app.view_functions .

Exemple de script:

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

Résultat de l'exécution du script ci-dessus:

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

route1
<function route1 at 0x128f1b9d8>

route2
<function route2 at 0x128f1ba60>

(Notez l'inclusion de la route "statique", créée automatiquement par Flask.)

1
Mark Amery

Vous pouvez afficher tous les itinéraires via flask Shell) en exécutant les commandes suivantes après avoir exporté ou défini la variable d’environnement FLASK_APP. flask Shell app.url_map

0
Xerrex