Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically generate Flask routes

Tags:

python

flask

I am trying to dynamically generate routes in Flask from a list. I want to dynamically generate view functions and endpoints and add them with add_url_rule.

This is what I am trying to do but I get a "mapping overwrite" error:

routes = [
    dict(route="/", func="index", page="index"),
    dict(route="/about", func="about", page="about")
]

for route in routes:
    app.add_url_rule(
        route["route"], #I believe this is the actual url
        route["page"], # this is the name used for url_for (from the docs)
        route["func"]
    )
    app.view_functions[route["func"]] = return render_template("index.html")
like image 538
Jesse Avatar asked Jul 17 '16 03:07

Jesse


People also ask

How do I add a dynamic URL to my flask?

How to create dynamic URLs in Python Flask with url_for()? To create dynamic URLs in Python Flask with url_for(), we can call url_for with the name of the view function and the URL parameter values. @app. route('/<variable>/add', methods=['GET', 'POST']) def add(variable): # ...

What is Url_for in flask?

Flask – URL Building Advertisements. The url_for() function is very useful for dynamically building a URL for a specific function. The function accepts the name of a function as first argument, and one or more keyword arguments, each corresponding to the variable part of URL.

Can we have multiple URL paths pointing to the same route function?

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. The code below shows how you use the a function for multiple URLs.


2 Answers

You have one problem with two possible solutions. Either:

  1. Have route[func] directly reference a function, not a string. In this case, you don't have to assign anything to app.view_functions.

Or:

  1. Leave out the third argument of app.add_url_rule, and assign a function to app.view_functions[route["page"]]. The code

    return render_template("index.html")
    

    is not a function. Try something like

    def my_func():
        return render_template("index.html")
    # ...
    app.view_functions[route["page"]] = my_func
    

I'd recommend the first option.

Source: the docs.


Alternate solution:

Use variable parts in the URL. Something like this:

@app.route('/<page>')
def index(page):
  if page=='about':
     return render_template('about.html') # for example
  else:
     some_value = do_something_with_page(page) # for example
     return render_template('index.html', my_param=some_value)
like image 88
A. Vidor Avatar answered Dec 29 '22 07:12

A. Vidor


Not too familiar with Flask, so it is possible that there is a cleaner way to do this. (If someone who is knowledgeable about Flask thinks that my method is inherently wrong, I'll gladly delete my answer if they explain why in a comment.) Now that I got that disclaimer out of the way, here are my thoughts:

app.route("/") is a decorator function. The @ notation is just syntactic sugar for something like index = app.route("/")(index). Therefore, you should be able to do something like this...

routes = [
    ("/", index),
    ("/about", about)
]
for route, view_func in routes:
    view_func = app.route(route)(view_func)

which would allow you to create the Flask routes from dynamically created routes and functions.

like image 42
pzp Avatar answered Dec 29 '22 08:12

pzp