5

I have following code:

application = tornado.web.Application([
    (r"/get(.*)", GetHandler),
])

class GetHandler(tornado.web.RequestHandler):
    def get(self, key):
        response = {'key': key}
        self.write(response)

when I go to localhost:port/get?key=python I receive empty key value {'key': ''}. What is wrong here?

Rudziankoŭ
  • 10,681
  • 20
  • 92
  • 192

2 Answers2

12

(.*) in regex matches everything. So this — (r"/get(.*)", GetHandler) — will match anything followed by /get, example:

/get
/getsomething
/get/something
/get.asldfkj%5E&(*&fkasljf

Let's say a request comes in at localhost:port/get/something, then the value of key argument in GetHandler.get(self, key) will be /something (yes, including the slash because .* matches everything).

But if a request comes in at localhost:port/get?key=python, the value of key argument in GETHandler.get(self, key) will be an empty string. It happens because the part containing ?key=python is called a Query String. It's not part of the url path. Tornado (or almost every other web framework) doesn't pass this to the view as an argument.


There are two ways you can change your code:

  1. If you want to access your view like this - localhost:port/get?key=python, you'll need to make changes to your url config and to your view:

    application = tornado.web.Application([
        (r"/get", GetHandler),
    ])
    
    class GetHandler(tornado.web.RequestHandler):
        def get(self):
            key = self.get_argument('key', None)
            response = {'key': key}
            self.write(response)
    
  2. If you don't want to change your app url config and your view, you'll need to make the request like this - localhost:port/get/python.
    But still you'll need to make a small change to your url config. Add a slash - / - between get and (.*), because otherwise the value of key would be /python instead of python.

    application = tornado.web.Application([
        (r"/get/(.*)", GetHandler), # note the slash
    ])
    
xyres
  • 20,487
  • 3
  • 56
  • 85
0

I hope that you will figure what you did wrong by yourself - that's a task for you.

Your working code:

import tornado.ioloop
import tornado.web

class GetHandler(tornado.web.RequestHandler):
    def get(self):
        response = self.get_arguments("key")
        if len(response) == 0:
            # Handle me
            self.set_status(400)
            return self.finish("Invalid key")
        self.write({"key":self.get_argument("key")})


def make_app():
    return tornado.web.Application([
        (r"/", GetHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
Ickerday
  • 67
  • 1
  • 7
Argus Malware
  • 773
  • 7
  • 19