2014-11-06 36 views
0

我想写一个简单的函数,让我从重复创建AsyncHTTPClientHTTPRequest并做client.fetch释放我。如何制作简化与龙卷风AsyncHTTPClient请求的包装?

现在,我想出了下面的代码:

def async_fetch(url, method='GET', headers={}, body=None): 
    '''Fetch an HTTP resource asynchronously 
     using `tornado.httpclient.AsyncHTTPClient` 
    ''' 

    if isinstance(body, dict): 
     body = urlencode(body) 

    request = HTTPRequest(url, method=method, headers=headers, body=body) 
    client = AsyncHTTPClient() 
    response = yield client.fetch(request) 
    return response.body 

显然,这是行不通的。它本身返回一个生成器,我不知道如何将它应用到RequestHandler中。

我只能返回client.fetch(client),这是一个任务,并且在处理程序中产生这个任务,但是我想要处理响应。

任何提示?谢谢!

回答

0

如果您使用tornado >=3您可以使用gen.Return创建返回一些定制协程:

@gen.coroutine 
def async_fetch(url, method='GET', headers={}, body=None): 
    async_http_client = AsyncHTTPClient() 
    http_request = HTTPRequest(url, method=method, headers=headers, body=body) 
    http_response = yield client.fetch(http_request) 
    raise gen.Return(http_response) # That's how return looks in tornado 

class MyHandler(RequestHandler): 
    @gen.coroutine 
    def get(): 
     ... 
     response = yield async_fetch('http://example.org') 
     ... 

在龙卷风2.xa需要更多的世俗的做法:

@gen.engine 
def async_fetch(url, method='GET', headers={}, body=None, callback=None): 
    async_http_client = AsyncHTTPClient() 
    http_request = HTTPRequest(url, method=method, headers=headers, body=body) 
    http_response = yield client.fetch(http_request) 
    if callback: 
     callback(http_response) 

class MyHandler(RequestHandler): 
    @web.asynchronous 
    @gen.engine 
    def get(): 
     ... 
     response = yield gen.Task(async_fetch, 'http://example.org') 
     ... 

你可能甚至去进一步并从async_fetch返回gen.Task的实例。

更新 两个gen.coroutinegen.Return是有价值的。 gen.coroutine允许从另一个调用一个协程(yield client.fetch(..))。 gen.Return允许从发生器返回一些值。两者都被引入来克服Python的局限性 - yield from构造的缺失。

+0

谢谢!我正在检查。没想到它那么简单。同时我在文档中记得它提到gen.Return与3.3之后的Python返回相同。所以我猜关键不是gen.Return,而是协程装饰器? – 2014-11-06 09:57:45

+0

@KenetJervet查看更新。希望它会有用。 – Vladimir 2014-11-06 10:44:57