What would be the appropriate way of resolving a URL within Flask to retrieve a reference to the endpoint as well as a dictionary of all the arguments?
To provide an example, given this route, I'd like to resolve '/user/nick'
to profile
,{'username': 'nick'}
:
@app.route('/user/<username>')
def profile(username): pass
From my research so far, all routes in Flask are stored under app.url_map
. The map is an instance of werkzeug.routing.Map and it has a method match()
that would in principle do what I am looking for. However, that method is internal to the class.
The url_for() function is used to build a URL to the specific function dynamically. The first argument is the name of the specified function, and then we can pass any number of keyword argument corresponding to the variable part of the URL.
How do you pass arguments in Flask API? Required Arguments To require a value be passed for an argument, just add required=True to the call to add_argument() . parser. add_argument('name', required=True, help="Name cannot be blank!")
Routing in FlaskThe route() decorator in Flask is used to bind an URL to a function. As a result when the URL is mentioned in the browser, the function is executed to give the result. Here, URL '/hello' rule is bound to the hello_world() function.
This is what I hacked for this purpose looking at url_for()
and reversing it:
from flask.globals import _app_ctx_stack, _request_ctx_stack
from werkzeug.urls import url_parse
def route_from(url, method = None):
appctx = _app_ctx_stack.top
reqctx = _request_ctx_stack.top
if appctx is None:
raise RuntimeError('Attempted to match a URL without the '
'application context being pushed. This has to be '
'executed when application context is available.')
if reqctx is not None:
url_adapter = reqctx.url_adapter
else:
url_adapter = appctx.url_adapter
if url_adapter is None:
raise RuntimeError('Application was not able to create a URL '
'adapter for request independent URL matching. '
'You might be able to fix this by setting '
'the SERVER_NAME config variable.')
parsed_url = url_parse(url)
if parsed_url.netloc is not "" and parsed_url.netloc != url_adapter.server_name:
raise NotFound()
return url_adapter.match(parsed_url.path, method)
The return value of this method is a tuple, with the first element being the endpoint name and the second a dictionary with the arguments.
I haven't tested it extensively, but it worked for me in all cases.
I know I am coming in late with an answer, but I ran into the same problem and found a simpler way to get it: request.view_args
. For example:
In my views:
@app.route('/user/<username>')
def profile(username):
return render_template("profile.html")
In profile.html
:
{{request.view_args}}
When visiting the url http://localhost:4999/user/sam
, I get: {'username': u'sam'}
.
You can also get the name of the function that got your view with request.endpoint
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With