I want to write a simple function that releases me from repeatedly creating AsyncHTTPClient
and HTTPRequest
and doing client.fetch
.
Now I came up with the following code:
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
Obviously this will not work. It returns a generator itself and I don't know how to apply it in a RequestHandler.
I can merely return client.fetch(client)
, which is a task, and yield this task in the handler, but I want the processing of the response wrapped out as well.
Any hints? Thanks!
If you're using tornado >=3 you may create custom coroutine that returns something using 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')
...
In tornado 2.x a more wordly approach is required:
@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')
...
You may go even further and return an instance of gen.Task
from async_fetch
.
Update Both gen.coroutine
and gen.Return
are valuable. gen.coroutine
allows to call one coroutine from another (yield client.fetch(..)
). gen.Return
allows to return some value from generator. Both were introduced to overcome Python <3.4 limitations -- the lack of yield from
construction.
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加