pythonflaskwerkzeug

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

Solution

  • 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.