Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List all available routes in Flask, along with corresponding functions' docstrings

Tags:

python

flask

I'm writing a small API, and wanted to print a list of all available methods along with the corresponding "help text" (from the function's docstring). Starting off from this answer, I wrote the following:

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api', methods = ['GET'])
def this_func():
    """This is a function. It does nothing."""
    return jsonify({ 'result': '' })

@app.route('/api/help', methods = ['GET'])
    """Print available functions."""
    func_list = {}
    for rule in app.url_map.iter_rule():
        if rule.endpoint != 'static':
            func_list[rule.rule] = eval(rule.endpoint).__doc__
    return jsonify(func_list)

if __name__ == '__main__':
    app.run(debug=True)

Is there a better -- safer -- way of doing this? Thanks.

like image 810
iandexter Avatar asked Jun 22 '13 10:06

iandexter


People also ask

What are routes in Flask?

Flask – Routing It is useful to access the desired page directly without having to navigate from the home page. The route() decorator in Flask is used to bind URL to a function. For example − @app. route('/hello') def hello_world(): return 'hello world' Here, URL '/hello' rule is bound to the hello_world() function.

How can I use the same route for multiple functions in Flask?

In some cases you can reuse a Flask route function for multiple URLs. Or you want the same page/response available via multiple URLs. In that case you can add a second route to the function by stacking a second route decorator to the function.

What is the default route request in Flask?

What is the default route request in Flask? By default, a route only answers to GET requests. You can use the methods argument of the route() decorator to handle different HTTP methods. If GET is present, Flask automatically adds support for the HEAD method and handles HEAD requests according to the HTTP RFC.


2 Answers

There is app.view_functions. I think that is exactly what you want.

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api', methods = ['GET'])
def this_func():
    """This is a function. It does nothing."""
    return jsonify({ 'result': '' })

@app.route('/api/help', methods = ['GET'])
def help():
    """Print available functions."""
    func_list = {}
    for rule in app.url_map.iter_rules():
        if rule.endpoint != 'static':
            func_list[rule.rule] = app.view_functions[rule.endpoint].__doc__
    return jsonify(func_list)

if __name__ == '__main__':
    app.run(debug=True)
like image 90
falsetru Avatar answered Sep 19 '22 17:09

falsetru


Here's mine:

@app.route("/routes", methods=["GET"])
def getRoutes():
    routes = {}
    for r in app.url_map._rules:
        routes[r.rule] = {}
        routes[r.rule]["functionName"] = r.endpoint
        routes[r.rule]["methods"] = list(r.methods)

    routes.pop("/static/<path:filename>")

    return jsonify(routes)

Gives:

{
    "/": {
        "functionName": "index",
        "methods": [
            "HEAD",
            "OPTIONS",
            "GET"
        ]
    },
    "/gen": {
        "functionName": "generateJobs",
        "methods": [
            "HEAD",
            "OPTIONS",
            "GET"
        ]
    },
    "/jobs": {
        "functionName": "getJobs",
        "methods": [
            "HEAD",
            "OPTIONS",
            "GET"
        ]
    },
    "/jobs/submit": {
        "functionName": "postJob",
        "methods": [
            "POST",
            "OPTIONS"
        ]
    },
    "/jobs/update/<id>": {
        "functionName": "updateJob",
        "methods": [
            "POST",
            "OPTIONS"
        ]
    },
    "/routes": {
        "functionName": "getRoutes",
        "methods": [
            "HEAD",
            "OPTIONS",
            "GET"
        ]
    }
}
like image 32
copeland3300 Avatar answered Sep 17 '22 17:09

copeland3300