Rudziankoŭ
Rudziankoŭ

Reputation: 11251

Tornado: asynchronous endpoints

I have following code:

class StackOverflowHandler(tornado.web.RequestHandler):

    def get(self, look_up_pattern):
        url = "https://api.stackexchange.com/2.2/search?order=desc&sort=votes&intitle=%s&site=stackoverflow"
        response = self.async_get(url)
        print(response)
        self.write(response)

    @gen.coroutine
    def async_get(self, url):
        link = httpclient.AsyncHTTPClient()
        request = httpclient.HTTPRequest(url)
        response = yield link.fetch(request)
        data = response.body.decode('utf-8')
        data = json.loads(data)
        return data

application = tornado.web.Application([
    (r"/search/(.*)", StackOverflowHandler),
])

The type that returns from async_get is tornado.concurrent.Future.

The exception is:

TypeError: write() only accepts bytes, unicode, and dict objects

I am new to asynchronous programming, please point me out my mistake.

Upvotes: 2

Views: 250

Answers (1)

kwarunek
kwarunek

Reputation: 12587

Since async_get is coroutine it returns Future object. To get "real" results, Future must be resolved - it need to be yielded. More over the get handler must be decorated as asynchronous as well

class StackOverflowHandler(tornado.web.RequestHandler):

    @gen.coroutine
    def get(self, look_up_pattern):
        url = "https://api.stackexchange.com/2.2/search?order=desc&sort=votes&intitle=%s&site=stackoverflow"
        response = yield self.async_get(url)
        print(response)
        self.write(response)

    @gen.coroutine
    def async_get(self, url):
        link = httpclient.AsyncHTTPClient()
        request = httpclient.HTTPRequest(url)
        response = yield link.fetch(request)
        data = response.body.decode('utf-8')
        data = json.loads(data)
        return data

Upvotes: 3

Related Questions