Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the Flask view function that matches a url

I have some url paths and want to check if they point to a url rule in my Flask app. How can I check this using Flask?

from flask import Flask, json, request, Response

app = Flask('simple_app')

@app.route('/foo/<bar_id>', methods=['GET'])
def foo_bar_id(bar_id):
    if request.method == 'GET':
        return Response(json.dumps({'foo': bar_id}), status=200)

@app.route('/bar', methods=['GET'])
def bar():
    if request.method == 'GET':
        return Response(json.dumps(['bar']), status=200)
test_route_a = '/foo/1'  # return foo_bar_id function
test_route_b = '/bar'  # return bar function
like image 466
Phillip Martin Avatar asked Jul 20 '16 18:07

Phillip Martin


1 Answers

app.url_map stores the object that maps and matches rules with endpoints. app.view_functions maps endpoints to view functions.

Call match to match a url to an endpoint and values. It will raise 404 if the route is not found, and 405 if the wrong method is specified. You'll need the method as well as the url to match.

Redirects are treated as exceptions, you'll need to catch and test these recursively to find the view function.

It's possible to add rules that don't map to views, you'll need to catch KeyError when looking up the view.

from werkzeug.routing import RequestRedirect, MethodNotAllowed, NotFound

def get_view_function(url, method='GET'):
    """Match a url and return the view and arguments
    it will be called with, or None if there is no view.
    """

    adapter = app.url_map.bind('localhost')

    try:
        match = adapter.match(url, method=method)
    except RequestRedirect as e:
        # recursively match redirects
        return get_view_function(e.new_url, method)
    except (MethodNotAllowed, NotFound):
        # no match
        return None

    try:
        # return the view function and arguments
        return app.view_functions[match[0]], match[1]
    except KeyError:
        # no view is associated with the endpoint
        return None

There are many more options that can be passed to bind to effect how matches are made, see the docs for details.

The view function can also raise 404 (or other) errors, so this only guarantees that a url will match a view, not that the view returns a 200 response.

like image 82
davidism Avatar answered Oct 21 '22 01:10

davidism