Search code examples
pythonflask

Python: Build Route Handlers Programatically


I'm building what should be a simple CRUD app with a Flask backend. Most of my endpoints have the exact same operations:

  1. Return a list of items
  2. Ingest a list from CSV

The only differentiators being the specific database table to draw from. I want to save time by defining these routes programatically. Something like this:

def define_routes(app):
    ROUTES = {
        '/list1': lambda : handle_list(model1),
        '/list2': lambda : handle_list(model2),
        # ...
    }

    for url in ROUTES:
        app.add_url_rule(url, view_func=ROUTES[url])

def handle_list(dbModel):
    if request.method == 'GET':
        # return the list
    
    if request.method == 'POST':
        # ingest the list

but when I try to run this I get this error: AssertionError: View function mapping is overwriting an existing endpoint function: <lambda>

Why am I getting this error when I use anonymous lambda functions? Is there a way to do what I'm trying to do?


Solution

  • The function passed to the view_func attribute requires a unique __name__ attribute. If this is not the case, as with a lambda expression, the function, as you noted, cannot be assigned.

    My spontaneous solution approach would be to generate and assign the required attribute from the rule. Here is an example that certainly needs to be revised.

    import re 
    
    def register_routes(app):
        ROUTES = {
            '/list-1': lambda: handle_list(model1), 
            '/list-2': lambda: handle_list(model2), 
            '/path/to/list-3': lambda: handle_list(model3)
        }
        for k,v in ROUTES.items():
            f = v
            f.__name__ = re.sub(r'[\s\-/]', r'_', k[1:])
            app.add_url_rule(k, view_func=f, methods=('GET', 'POST',))