Tornado URL query parameters Tornado URL query parameters python python

Tornado URL query parameters


There is a better way for GET requests. There is a demo in the tornado source on github here

# url handlerhandlers = [(r"/entry/([^/]+)", EntryHandler),]class EntryHandler(BaseHandler):    def get(self, slug):        entry = self.db.get("SELECT * FROM entries WHERE slug = %s", slug)        if not entry: raise tornado.web.HTTPError(404)        self.render("entry.html", entry=entry)

Any "text" that matches the regular expression will be passed to the EntryHandler's get method as slug argument. If the url doesn't match any handler, the user will receive a 404 error.

If you wanted to provide another fallback, you could make the parameter optional

(r"/entry/([^/]*)", EntryHandler),class EntryHandler(BaseHandler):    def get(self, slug=None):        pass

Update:

+1 for the link. However does this URL pattern extend to include more parameters if I wanted to search like this... /recipes?ingredient=chicken&style=indian – colinjameswebb

Yes it does.

handlers = [     (r'/(\d{4})/(\d{2})/(\d{2})/([a-zA-Z\-0-9\.:,_]+)/?', DetailHandler)]class DetailHandler(BaseHandler):    def get(self, year, month, day, slug):        pass


get_argument allows you to provide a default value:

details=self.get_argument("details", None, True)

If it is provided, then no exception will occur if the argument isn't provided


Tornado also has a get_arguments function. It returns a list of arguments with the given name. If not present, it returns an empty list ( [] ). I found it cleaner this way to sanitize your web service inputs instead of try..catch blocks.

Sample:
Assume I have a following URL handler:

(r"/recipe",GetRecipe)

And the request handler:

class GetRecipe(RequestHandler):    def get(self):        recipe_id = self.get_arguments("rid")        if recipe_id == []:            # Handle me            self.set_status(400)            return self.finish("Invalid recipe id")        self.write({"recipe_id":self.get_argument("rid")})


recipe_id list will also hold the value but I found self.get_argument usage convenient this way.

Now for the results:

curl "http://localhost:8890/recipe" -v*   Trying 127.0.0.1...* Connected to localhost (127.0.0.1) port 8890 (#0)> GET /recipe HTTP/1.1> User-Agent: curl/7.35.0> Host: localhost:8890> Accept: */*> < HTTP/1.1 400 Bad Request< Content-Length: 17< Content-Type: text/html; charset=UTF-8* Server TornadoServer/1.1.1 is not blacklisted< Server: TornadoServer/1.1.1< * Connection #0 to host localhost left intactInvalid recipe idcurl "http://localhost:8890/recipe?rid=230" -v*   Trying 127.0.0.1...* Connected to localhost (127.0.0.1) port 8890 (#0)> GET /recipe?rid=230 HTTP/1.1> User-Agent: curl/7.35.0> Host: localhost:8890> Accept: */*> < HTTP/1.1 200 OK< Content-Length: 20< Etag: "d69ecb9086a20160178ade6b13eb0b3959aa13c6"< Content-Type: text/javascript; charset=UTF-8* Server TornadoServer/1.1.1 is not blacklisted< Server: TornadoServer/1.1.1< * Connection #0 to host localhost left intact{"recipe_id": "230"}