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.

Asked By: Igor Chubin

||

Answers:

Simply use request.path.

from flask import request

...

@app.route("/antitop/")
@app.route("/top/")
@requires_auth
def show_top():
    ... request.path ...
Answered By: falsetru

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.

Answered By: Daniel Roseman

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'
Answered By: thkang

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
    ...
Answered By: iurisilvio

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
Answered By: marcinkuzminski

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.

Answered By: Criomby
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.