CDT
CDT

Reputation: 10661

Tornado - How to get response of AsynHTTPClient.fetch()?

#!/usr/bin/env python

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient

import urllib
import json
import datetime
import time

from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)

config = {
        'proxy_host': '58.59.21.228',
        'proxy_port': 25,
        'proxy_username': 'yz',
        'proxy_password': 'fangbinxingqusi',
}

def handle_request(response):
    if response.error:
        print "Error:", response.error

tornado.httpclient.AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        client = tornado.httpclient.AsyncHTTPClient()
        response = client.fetch("http://twitter.com/", handle_request,
                **config)
        self.write(response.body)

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"/", IndexHandler)],
            debug=True)
    httpserver = tornado.httpserver.HTTPServer(app)
    httpserver.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

At running, response object in the get() method is reported to be a None type. How can I get the response of the fetch() method in the get() method?

Upvotes: 2

Views: 9749

Answers (1)

lbolla
lbolla

Reputation: 5411

You are using the AsyncHTTPClient, therefore the fetch method does not return anything. You need to use the "asynchronous" decorator and remember to call finish in the callback called by fetch.

Here is the code:

import tornado.httpserver                                                    
import tornado.ioloop                                                        
import tornado.options                                                       
import tornado.web                                                           
import tornado.httpclient                                                    

from tornado.options import define, options                                  
define("port", default=8000, help="run on the given port", type=int)         

config = {                                                                   
    'proxy_host': '58.59.21.228',                                            
    'proxy_port': 25,                                                        
    'proxy_username': 'yz',                                                  
    'proxy_password': 'fangbinxingqusi',                                     
}                                                                            

tornado.httpclient.AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")


class IndexHandler(tornado.web.RequestHandler):                              

    @tornado.web.asynchronous                                                
    def get(self):                                                           
        client = tornado.httpclient.AsyncHTTPClient()                        
        client.fetch("http://twitter.com/", self.handle_request, **config)   

    def handle_request(self, response):                                      
        if response.error:                                                   
            print("Error:", response.error)                                  
        else:                                                                
            self.write(response.body)                                        
        self.finish()                                                        


if __name__ == "__main__":                                                   
    tornado.options.parse_command_line()                                     
    app = tornado.web.Application(handlers=[(r"/", IndexHandler)], debug=True)
    httpserver = tornado.httpserver.HTTPServer(app)                          
    httpserver.listen(options.port)                                          
    tornado.ioloop.IOLoop.instance().start()             

You can also use Tornado's gen to make your handler prettier:

class IndexHandler(tornado.web.RequestHandler):                              

    @tornado.web.asynchronous                                                
    @tornado.gen.engine                                                      
    def get(self):                                                           
        client = tornado.httpclient.AsyncHTTPClient()                        
        response = yield tornado.gen.Task(client.fetch, "http://twitter.com/",
                                        **config)                            
        if response.error:                                                   
            self.write("Error: %s" % response.error)                         
        else:                                                                
            self.write(response.body)                                        

        self.finish()                                                        

Upvotes: 9

Related Questions