9

I am writing an app in which users will be able to store information that they can specify a REST interface for. IE, store a list of products at /<username>/rest/products. Since the URLs are obviously not known before hand, I was trying to think of the best way to implement dynamic URL creation in Flask. The first way I thought of would be to write a catch-all rule, and route the URL from there. But then I am basically duplicating URL routing capabilities when Flask already has them built-in. So, I was wondering if it would be a bad idea to use .add_url_rule() (docs here, scroll down a bit) to attach them directly to the app. Is there a specific reason this shouldn't be done?

2 Answers 2

11

Every time you execute add_url_rule() the internal routing remaps the URL map. This is neither threadsafe nor fast. I right now don't understand why you need user specific URL rules to be honest. It kinda sounds like you actually want user specific applications mounted?

Maybe this is helpful: http://flask.pocoo.org/docs/patterns/appdispatch/

Sign up to request clarification or add additional context in comments.

3 Comments

I have the same requirement i.e. I'm looking for a way to dynamically add new endpoints to an API built with Eve using its register_resource method, which calls add_url_rule internally. Note that this won't happen for every request, only triggered by a hook when a POST to a specific endpoint is received so performance should not be an issue.
Exactly the same requirement here. Api, that needs adding and removing a new route whenever a PUT request happen at certain route. In my case i'm using flask-restful, but basically is the same.
It seems I can do this in before_request if I use threading.lock, however, I'm not sure how to stop issues with url_for having the following error: ValueError: list modified during sort ERROR:app:Internal Server Error, list modified during sort
0

I have had similar requirement for my application where each endpoint /<SOMEID>/rest/other for given SOMEID should be bounded to a different function. One way to achieve this is keeping a lookup dictionary where values are the function that handle the specific SOMEID. For example take a look at this snippet:

func_look_up_dict = {...}
@app.route('<SOMEID>/rest/other', methods=['GET'])
def multiple_func_router_endpoint(SOMEID):
    if SOMEID in func_look_up_dict.keys():
        return jsonify({'result' = func_look_up_dict[SOMEID]()}), 200
    else:
        return jsonify({'result'='unknown', 'reason'='invalid id in url'}), 404

so for this care you don't really need to "dynamically" add url rules, but rather use a url rule with parameter and handle the various cases withing a single function. Another thing to consider is to really think about the use case of such URL endpoint. If <username> is a parameter that needs to be passed in, why not to use a url rule such as /rest/product/<username> or pass it in as an argument in the GET request? Hope that helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.