Edited my question because it wasn't very clear before.
Code 1 working
class AtSeaHandler(webapp2.RequestHandler):
def get(self, id=None):
boat = ndb.Key(urlsafe=id).get()
boat_dict = boat.to_dict()
boat_dict['self'] = "/boats/" + id
self.response.write(json.dumps(boat_dict)
app = webapp2.WSGIApplication([
('/boats/([\w-]+)', AtSeaHandler)
], debug=True)
Code 2 (not working)
class AtSeaHandler(webapp2.RequestHandler):
def get(self, id=None):
boat = ndb.Key(urlsafe=id).get()
boat_dict = boat.to_dict()
boat_dict['self'] = "/boats/" + id
self.response.write(json.dumps(boat_dict)
app = webapp2.WSGIApplication(
('/boats/([\w-]+)/at_sea', AtSeaHandler)
], debug=True)
Code 2 is a copy of code 1. Only difference between code 1 and code 2 is code 1 is ('/boats/([\w-]+)', AtSeaHandler) vs code 2 is ('/boats/([\w-]+)/at_sea', AtSeaHandler). Then I comment out code 1.
code 1 works. code 2 doesn't work with the /at_sea added. I entered http://localhost:8080/boats/aghkZXZ-Tm9uZXIRCxIEQm9hdBiAgICAgPCLCww in postman and verifies code 1 works. Also tested code 2 and verifies it doesn't work.
What do I need to do to get this to work? When I passed a boat
entity key to ([\w-]+) and I def get(self, id=None):
id
is given the boat entity key. Does at_sea need an argument in get()? Do i need to change the get() from get(self, id=none) to get(self, id=none, argument3=none)? Coming from C++, I keep thinking that it is like a function call with 3 arguments needs a function header with 3 parameters to hold those arguments. Am I totally misunderstanding things?
The documentation isn't helping me understand how to answer my question...
You can always do a tryout using a generic approach in the handler's get()
code (whcih you can easily check with your browser), in the sense that it should work regardless of the regex pattern you have in the app
's router:
def get(self, *args, **kwargs):
self.response.write('args: %s<br>kwargs: %s' % (args, kwargs))
The router works the same way for the put()
, so you could apply a similar method, only it's a bit more difficult to see the results immediately - you'd have to use logging and check the app's logs.
With this you see exactly what args you get and how/where, so you can adapt your handler code as needed. You may need to repeat if you change the regex pattern.
With the code you posted (i.e. def put():
) it shouldn't have worked at all as id
is uninitialized. Which means you probably lost track of your changes.
To me put(self, id=None):
is correct and should work for any pattern with a single ()
group in it.
You didn't exactly explain what do you mean by stopped working
:) I have 2 suspicions:
you didn't change the actual request to match the pattern. I mean a boats/<some_safe_url>
request would match the '/boats/([\w-]+)'
pattern, but will fail the '/boats/([\w-]+)/at_sea'
pattern. You'd see a 404 error.
you expected the request on AtSeaHandler
, but you actually got it on BoatHandler
(and maybe you didn't notice that). This happens because a boats/<some_safe_url>/at_sea
pattern also matches the '/boats/(.*)'
pattern and the router selects the first match. This unexpected match also produces an invalid id
: <some_safe_url>/at_sea
which will fail to get you a key and thus a boat - again a 404 error, or plain crash - a 500 error. You need to swap the order of the route definitions in the router, with the most specific pattern first.