Flask-restful: add_resource with multiple paths; inconsistent syntax windows<->linux

Created on 5 Jul 2015  路  2Comments  路  Source: flask-restful/flask-restful

I want to use one resource with two endpoints. The first one uses GET to fetch an object with a given id. The second one is used by POST when calling a function on an object with a given ID.
On Windows, this works:

api.add_resource(Shipment,              '/shipments/<int:id>')
api.add_resource(Shipment,              '/shipments/<int:id>/<string:action>')

But on Linux, it doesn't and results in an error:

File "/flask/lib/python2.7/site-packages/flask/app.py", line 984, in add_url_rule
    'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint function: shipment

Here I can solve it by using both paths in one add_resource:
api.add_resource(Shipment, '/shipments/<int:id>', '/shipments/<int:id>/<string:action>')
This also works on Windows.

Looking at the docs I believe the latter is the 'official' way of doing this, though I like the Windows way where every add_resource call seems to add to the list of enabled URLs.
Shouldn't this behaviour at least be consistend accross platforms?

And (maybe this should be a separate issue?), wouldn't it be better if the list of given URLs would be either ONE URL as a regular string, of MULTIPLE URLs given as a list, instead of a series of strings?

Most helpful comment

I don't think this has anything to do with Windows vs. Linux. Please check your version of Flask on both systems. Flask 0.9 did not have a check for adding a route to the same view function multiple times, whereas 0.10 and after will throw that exception you are seeing.

Regarding your other question, such a change would not be backwards compatible and I'd rather not break it. Could you elaborate why you think passing a list instead would be more correct? Both ways feel approximately equivalent to me. If you feel more comfortable using a list instead, you could do this:

routes = [
    '/shipments/<int:id>',
    '/shipments/<int:id>/<string:action>',
]

api.add_resource(Shipment, *routes)

All 2 comments

I don't think this has anything to do with Windows vs. Linux. Please check your version of Flask on both systems. Flask 0.9 did not have a check for adding a route to the same view function multiple times, whereas 0.10 and after will throw that exception you are seeing.

Regarding your other question, such a change would not be backwards compatible and I'd rather not break it. Could you elaborate why you think passing a list instead would be more correct? Both ways feel approximately equivalent to me. If you feel more comfortable using a list instead, you could do this:

routes = [
    '/shipments/<int:id>',
    '/shipments/<int:id>/<string:action>',
]

api.add_resource(Shipment, *routes)

My computer is the Linux one while a friend is running it on Windows; when he changed this code I started to see the error. I'm indeed running 0.10.1, so I think he might be running 0.9 (asked him bit didn't get a response yet).

Concerning the list; most of the times you define and call functions like this:

def myFunction(arg1, arg2, arg3):
    print arg1 # "first"
    print arg2 # 2
    print arg3 # 3

myFunction("first", 2, 3)

You call the function with as many arguments as you used when defining the function. So for me, when I use multiple arguments separated with comma's (the routes), it feels like I'm sending multiple arguments, instead of sending a single argument that happens to be a list.
If we change the function above to behave like add_resource, it would look something like this (pseudo-code):

def myFunction(arg1, arg2, arg3="some default):
    print arg1 # "first"
    print arg2 # 2, or [2, 3]?
    print arg3 # 3, or "some default"?

myFunction("first", 2, 3)

It's not clear anymore what's happening just from looking at the function call myFunction("first, 2, 3) Technically it doesn't work like this of course, but I hope you can see what I mean.

But, I guess in the end it's just be a matter of preference.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

svvitale picture svvitale  路  8Comments

ueg1990 picture ueg1990  路  4Comments

f9n picture f9n  路  4Comments

lra picture lra  路  4Comments

dmikhaylov picture dmikhaylov  路  5Comments