Che cos'è un 'endpoint' in Flask?


125

La documentazione di Flask mostra :

add_url_rule(*args, **kwargs)
      Connects a URL rule. Works exactly like the route() decorator.
      If a view_func is provided it will be registered with the endpoint.

     endpoint  the endpoint for the registered URL rule. Flask itself assumes the name of the view function as endpoint

Cosa si intende esattamente per "endpoint"?

Risposte:


267

Come funziona il Flask Routing

L'intera idea di Flask (e della libreria Werkzeug sottostante) è quella di mappare i percorsi URL su una logica che verrà eseguita (in genere, la "funzione di visualizzazione"). La vista di base è definita in questo modo:

@app.route('/greeting/<name>')
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

Si noti che la funzione a cui si fa riferimento (add_url_rule) raggiunge lo stesso obiettivo, semplicemente senza usare la notazione del decoratore. Pertanto, il seguente è lo stesso:

# No "route" decorator here. We will add routing using a different method below.
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

app.add_url_rule('/greeting/<name>', 'give_greeting', give_greeting)

Supponiamo che il tuo sito Web si trovi in ​​"www.example.org" e utilizzi la vista sopra. L'utente inserisce il seguente URL nel proprio browser:

http://www.example.org/greeting/Mark

Il compito di Flask è prendere questo URL, capire cosa vuole fare l'utente e passarlo a una delle tue numerose funzioni Python per la gestione. Prende il percorso :

/greeting/Mark

... e lo abbina all'elenco dei percorsi. Nel nostro caso, abbiamo definito questo percorso per passare alla give_greetingfunzione.

Tuttavia, mentre questo è il modo tipico in cui potresti creare una vista, in realtà estrae alcune informazioni extra da te. Dietro le quinte, Flask non ha fatto il salto direttamente dall'URL alla funzione di visualizzazione che dovrebbe gestire questa richiesta. Non dice semplicemente ...

URL (http://www.example.org/greeting/Mark) should be handled by View Function (the function "give_greeting")

In realtà, c'è un altro passaggio, in cui associa l'URL a un endpoint:

URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "give_greeting".
Requests to Endpoint "give_greeting" should be handled by View Function "give_greeting"

Fondamentalmente, "endpoint" è un identificatore utilizzato per determinare quale unità logica del codice deve gestire la richiesta . Normalmente, un endpoint è solo il nome di una funzione di visualizzazione. Tuttavia, è possibile modificare effettivamente l'endpoint, come nell'esempio seguente.

@app.route('/greeting/<name>', endpoint='say_hello')
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

Ora, quando Flask indirizza la richiesta, la logica appare così:

URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "say_hello".
Endpoint "say_hello" should be handled by View Function "give_greeting"

Come si utilizza l'endpoint

L'endpoint è comunemente usato per la "ricerca inversa". Ad esempio, in una vista dell'applicazione Flask, si desidera fare riferimento a un'altra vista (forse quando si collega da un'area del sito a un'altra). Anziché codificare l'URL, è possibile utilizzare url_for(). Supponi quanto segue

@app.route('/')
def index():
    print url_for('give_greeting', name='Mark') # This will print '/greeting/Mark'

@app.route('/greeting/<name>')
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

Questo è vantaggioso, poiché ora possiamo cambiare gli URL della nostra applicazione senza dover cambiare la linea in cui facciamo riferimento a quella risorsa.

Perché non usare sempre sempre il nome della funzione di visualizzazione?

Una domanda che potrebbe sorgere è la seguente: "Perché abbiamo bisogno di questo ulteriore livello?" Perché mappare un percorso a un endpoint, quindi un endpoint a una funzione di visualizzazione? Perché non saltare quel passaggio intermedio?

Il motivo è perché è più potente in questo modo. Ad esempio, i modelli Flask consentono di dividere l'applicazione in varie parti. Potrei avere tutte le mie risorse lato amministratore in un progetto chiamato "admin" e tutte le mie risorse a livello di utente in un endpoint chiamato "utente".

I progetti consentono di separarli in spazi dei nomi. Per esempio...

main.py:

from flask import Flask, Blueprint
from admin import admin
from user import user

app = Flask(__name__)
app.register_blueprint(admin, url_prefix='admin')
app.register_blueprint(user, url_prefix='user')

admin.py:

admin = Blueprint('admin', __name__)

@admin.route('/greeting')
def greeting():
    return 'Hello, administrative user!'

user.py:

user = Blueprint('user', __name__)
@user.route('/greeting')
def greeting():
    return 'Hello, lowly normal user!'

Si noti che in entrambi i progetti, il percorso '/ saluto' è una funzione chiamata "saluto". Se volessi fare riferimento alla funzione "saluto" dell'amministratore, non potrei semplicemente dire "saluto" perché esiste anche una funzione "saluto" dell'utente. Gli endpoint consentono una sorta di spazio dei nomi specificando il nome del progetto come parte dell'endpoint. Quindi, potrei fare quanto segue ...

print url_for('admin.greeting') # Prints '/admin/greeting'
print url_for('user.greeting') # Prints '/user/greeting'

1
Come su url_forper root? Ho Could not build url for endpoint ''
rilevato un

Mi è piaciuta molto la tua spiegazione e mi ha dato una buona idea di come funzionano questi endpoint. Tuttavia, ora che capisco questo concetto, penso che manchi un punto riguardante gli endpoint, in Flask in particolare. Se non si specificano gli endpoint, la regola nella url_for()funzione potrebbe essere infranta cambiando il nome di una funzione / classe per motivi X o Y (qualcuno ha refactored il codice e trovato un nome più appropriato, ecc ...). Gli endpoint generati automaticamente da Flask ti aiutano a gestire i cambiamenti di url. L'endpoint esplicito ti aiuta a gestire le modifiche all'URL e le modifiche al nome della tua funzione.
IMCinvia il

1
Questo chiarisce davvero la mia comprensione della funzionalità dell'endpoint di Flask e forse anche della definizione dell'endpoint in generale. Inoltre ho trovato qualche errore di battitura. La tua funzione di visualizzazione non dovrebbe essere give_greetinginvece di my_greeting? Non vedo da nessuna my_greetingparte ..
steveohmn,

23

Endpoint è il nome utilizzato per la ricerca inversa delle regole dell'URL url_fore per impostazione predefinita è il nome della funzione di visualizzazione.

Piccolo esempio:

from flask import Flask, url_for

app = Flask(__name__)

# We can use url_for('foo_view') for reverse-lookups in templates or view functions
@app.route('/foo')
def foo_view():
    pass

# We now specify the custom endpoint named 'bufar'. url_for('bar_view') will fail!
@app.route('/bar', endpoint='bufar')
def bar_view():
    pass

with app.test_request_context('/'):
    print url_for('foo_view')
    print url_for('bufar')
    # url_for('bar_view') will raise werkzeug.routing.BuildError
    print url_for('bar_view')
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.