Flask: get current route
Question:
In Flask, when I have several routes for the same function,
how can I know which route is used at the moment?
For example:
@app.route("/antitop/")
@app.route("/top/")
@requires_auth
def show_top():
....
How can I know, that now route was called using /top/
or /antitop/
?
UPDATE
I know about request.path
I don’t want use it, because the request can be rather complex, and I want repeat the routing logic in the function. I think that the solution with url_rule
it the best one.
Answers:
Simply use request.path
.
from flask import request
...
@app.route("/antitop/")
@app.route("/top/")
@requires_auth
def show_top():
... request.path ...
It seems to me that if you have a situation where it matters, you shouldn’t be using the same function in the first place. Split it out into two separate handlers, which each call a common fiction for the shared code.
the most ‘flasky’ way to check which route triggered your view is, by request.url_rule
.
from flask import request
rule = request.url_rule
if 'antitop' in rule.rule:
# request by '/antitop'
elif 'top' in rule.rule:
# request by '/top'
If you want different behaviour to each route, the right thing to do is create two function handlers.
@app.route("/antitop/")
@requires_auth
def top():
...
@app.route("/top/")
@requires_auth
def anti_top():
...
In some cases, your structure makes sense. You can set values per route.
@app.route("/antitop/", defaults={'_route': 'antitop'})
@app.route("/top/", defaults={'_route': 'top'})
@requires_auth
def show_top(_route):
# use _route here
...
Another option is to use endpoint variable:
@app.route("/api/v1/generate_data", methods=['POST'], endpoint='v1')
@app.route("/api/v2/generate_data", methods=['POST'], endpoint='v2')
def generate_data():
version = request.endpoint
return version
One thing I have to add to the answers above is that
request.path
preserves the url parameter value(s) passed while
request.url_rule
gives you the url_rule you defined without the passed parameter(s)
@app.route("/antitop/")
@app.route("/top/")
@requires_auth
def show_top():
request.path
request.url_rule
# -> both will give you "/antitop/" or "/top/"
....
@app.route("/antitop/<username>")
@app.route("/top/<username>")
@requires_auth
def show_top():
request.path
# -> gives you "/antitop/name" or ...
request.url_rule
# -> gives you "/antitop/<username>" or ...
....
Since you don’t have any variable routes definey (yet!) you don’t have to care but for the sake of saving you work and the headache in the future I’d still suggest using request.path
.
In Flask, when I have several routes for the same function,
how can I know which route is used at the moment?
For example:
@app.route("/antitop/")
@app.route("/top/")
@requires_auth
def show_top():
....
How can I know, that now route was called using /top/
or /antitop/
?
UPDATE
I know about request.path
I don’t want use it, because the request can be rather complex, and I want repeat the routing logic in the function. I think that the solution with url_rule
it the best one.
Simply use request.path
.
from flask import request
...
@app.route("/antitop/")
@app.route("/top/")
@requires_auth
def show_top():
... request.path ...
It seems to me that if you have a situation where it matters, you shouldn’t be using the same function in the first place. Split it out into two separate handlers, which each call a common fiction for the shared code.
the most ‘flasky’ way to check which route triggered your view is, by request.url_rule
.
from flask import request
rule = request.url_rule
if 'antitop' in rule.rule:
# request by '/antitop'
elif 'top' in rule.rule:
# request by '/top'
If you want different behaviour to each route, the right thing to do is create two function handlers.
@app.route("/antitop/")
@requires_auth
def top():
...
@app.route("/top/")
@requires_auth
def anti_top():
...
In some cases, your structure makes sense. You can set values per route.
@app.route("/antitop/", defaults={'_route': 'antitop'})
@app.route("/top/", defaults={'_route': 'top'})
@requires_auth
def show_top(_route):
# use _route here
...
Another option is to use endpoint variable:
@app.route("/api/v1/generate_data", methods=['POST'], endpoint='v1')
@app.route("/api/v2/generate_data", methods=['POST'], endpoint='v2')
def generate_data():
version = request.endpoint
return version
One thing I have to add to the answers above is that
request.path
preserves the url parameter value(s) passed while request.url_rule
gives you the url_rule you defined without the passed parameter(s)
@app.route("/antitop/")
@app.route("/top/")
@requires_auth
def show_top():
request.path
request.url_rule
# -> both will give you "/antitop/" or "/top/"
....
@app.route("/antitop/<username>")
@app.route("/top/<username>")
@requires_auth
def show_top():
request.path
# -> gives you "/antitop/name" or ...
request.url_rule
# -> gives you "/antitop/<username>" or ...
....
Since you don’t have any variable routes definey (yet!) you don’t have to care but for the sake of saving you work and the headache in the future I’d still suggest using request.path
.