Willian Fuks
Willian Fuks

Reputation: 11787

Tornado Not Interpreting URL

I've been trying to create a web service using Tornado Framework. The system is supposed to handle URLs such as the following:

IP:Port/?user=1822&catid=48&skus=AB1,FS35S,98KSU1

First I've created this code to read urls:

#!/usr/bin/env python

from datetime import date
import tornado.httpserver
import tornado.escape
import tornado.ioloop
import tornado.web

class WService(tornado.web.RequestHandler):
    def get(self, url):
        self.write("value of url: %s" %(url))

application = tornado.web.Application([
    (r"/([^/]+)", WService)])

if __name__ == "__main__":
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(9000)
    tornado.ioloop.IOLoop.instance().start()

and entering the url:

IP:Port/hello_world

resulted in:

value of url: hello_world

Any character used in the URL works, except for the "?". When changing the code such as:

application = tornado.web.Application([
        (r"/?([^/]+)", WService)])

and sent the url with the "?" mark (IP:Port/?hello_world) the result is:

404: Not Found

Researching about Tornado to solve this problem I found the get_argument method and tried to apply it, such as:

class WService2(tornado.web.RequestHandler):
    def get(self):
        user = self.get_argument('user', None)   
        respose = { 'user': user }   
        self.write(response)

and

application = tornado.web.Application([
    (r"/", WService2),   
])

But sending the URL IP:Port/user=5 returned:

404: Not Found

I also tried:

application = tornado.web.Application([
    (r"/(\w+)", WService2),   
])

And also:

application = tornado.web.Application([
    (r"/([^/]+)", WService2),   
])

and nothing worked.

Am I doing something wrong to read the URLs with the "?" marks and is there a reason why Tornado is not reading URLs with parameters such as the user one? Is there something missing?

I've updated Tornado to the lastest version but it didn't work as well.

If you need more information or something is not clear please let me know.

Thanks in advance,

Upvotes: 0

Views: 1390

Answers (1)

R Hyde
R Hyde

Reputation: 10409

The reason that you aren't seeing the entire string is that Tornado has already parsed it and placed it into a request object. If you want to see the entire path including the query string, then take a look at request.uri.

In your example, if you were to go to http://localhost:9000/hello_world?x=10&y=33 then request.uri would be set to /hello_world?x=10&y=33.

However, as you state, you are better off using get_argument (or get_arguments) to examine the arguments. Here's your example, augmented to show how you can read them.

Try going to http://localhost:9000/distance?x1=0&y1=0&x2=100&y2=100 and see what you get back.

Similarly, try, http://localhost:9000/?user=1822&catid=48&skus=AB1,FS35S,98KSU1. This should now work as you expected.

#!/usr/bin/env python

import math
import tornado.httpserver
import tornado.escape
import tornado.ioloop
import tornado.web


class DistanceService(tornado.web.RequestHandler):
    def get(self):
        x1 = float(self.get_argument('x1'))
        y1 = float(self.get_argument('y1'))
        x2 = float(self.get_argument('x2'))
        y2 = float(self.get_argument('y2'))
        dx = x1 - x2
        dy = y1 - y2
        magnitude = math.sqrt(dx * dx + dy * dy)
        self.write("the distance between the points is %3.2f" % magnitude)


class WService(tornado.web.RequestHandler):
    def get(self):
        self.write("value of request.uri: %s" % self.request.uri)
        self.write("<br>")
        self.write("value of request.path: %s" % self.request.path)
        self.write("<br>")
        self.write("value of request.query: %s" % self.request.query)


application = tornado.web.Application([
    (r"/distance", DistanceService),
    (r"/", WService),
])

if __name__ == "__main__":
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(9000)
    tornado.ioloop.IOLoop.instance().start()

Upvotes: 5

Related Questions