How to wrap asynchronous and gen functions together in Tornado? My code looks like below, the error is 'Future' object has no attribute 'body'.
Did I place the decorators in a wrong way?
import tornado.httpclient
import tornado.web
import tornado.gen
import tornado.httpserver
import tornado.ioloop
class Class1(tornado.web.RequestHandler):
@tornado.web.asynchronous
def post(self, *args, **kwargs):
url = self.get_argument('url', None)
response = self.json_fetch('POST', url, self.request.body)
self.write(response.body)
self.finish()
@tornado.gen.engine
def json_fetch(self, method, url, body=None, *args, **kwargs):
client = tornado.httpclient.AsyncHTTPClient()
headers = tornado.httputil.HTTPHeaders({"content-type": "application/json charset=utf-8"})
request = tornado.httpclient.HTTPRequest(url, method, headers, body)
yield tornado.gen.Task(client.fetch, request)
You don't need "asynchronous" in this code example. "gen.engine" is obsolete, use "coroutine" instead. You don't generally need to use "gen.Task" much these days, either. Make four changes to your code:
The result:
class ClubCreateActivity(tornado.web.RequestHandler):
@tornado.gen.coroutine
def post(self, *args, **kwargs):
url = self.get_argument('url', None)
response = yield self.json_fetch('POST', url, self.request.body)
self.write(response.body)
@tornado.gen.coroutine
def json_fetch(self, method, url, body=None, *args, **kwargs):
client = tornado.httpclient.AsyncHTTPClient()
headers = tornado.httputil.HTTPHeaders({"content-type": "application/json charset=utf-8"})
request = tornado.httpclient.HTTPRequest(url, method, headers, body)
response = yield client.fetch(request)
raise gen.Return(response)
Further reading: