tornado.gen
— Simplify asynchronous code¶
tornado.gen
is a generator-based interface to make it easier to
work in an asynchronous environment. Code using the gen
module
is technically asynchronous, but it is written as a single generator
instead of a collection of separate functions.
For example, the following asynchronous handler:
class AsyncHandler(RequestHandler):
@asynchronous
def get(self):
http_client = AsyncHTTPClient()
http_client.fetch("http://example.com",
callback=self.on_fetch)
def on_fetch(self, response):
do_something_with_response(response)
self.render("template.html")
could be written with gen
as:
class GenAsyncHandler(RequestHandler):
@gen.coroutine
def get(self):
http_client = AsyncHTTPClient()
response = yield http_client.fetch("http://example.com")
do_something_with_response(response)
self.render("template.html")
Most asynchronous functions in Tornado return a Future
;
yielding this object returns its result
.
You can also yield a list or dict of Futures
, which will be
started at the same time and run in parallel; a list or dict of results will
be returned when they are all finished:
@gen.coroutine
def get(self):
http_client = AsyncHTTPClient()
response1, response2 = yield [http_client.fetch(url1),
http_client.fetch(url2)]
response_dict = yield dict(response3=http_client.fetch(url3),
response4=http_client.fetch(url4))
response3 = response_dict['response3']
response4 = response_dict['response4']
If the singledispatch
library is available (standard in
Python 3.4, available via the singledispatch package on older
versions), additional types of objects may be yielded. Tornado includes
support for asyncio.Future
and Twisted’s Deferred
class when
tornado.platform.asyncio
and tornado.platform.twisted
are imported.
See the convert_yielded
function to extend this mechanism.
Changed in version 3.2: Dict support added.
Changed in version 4.1: Support added for yielding asyncio
Futures and Twisted Deferreds
via singledispatch
.
Decorators¶
-
tornado.gen.
coroutine
(func, replace_callback=True)[source]¶ Decorator for asynchronous generators.
Any generator that yields objects from this module must be wrapped in either this decorator or
engine
.Coroutines may “return” by raising the special exception
Return(value)
. In Python 3.3+, it is also possible for the function to simply use thereturn value
statement (prior to Python 3.3 generators were not allowed to also return values). In all versions of Python a coroutine that simply wishes to exit early may use thereturn
statement without a value.Functions with this decorator return a
Future
. Additionally, they may be called with acallback
keyword argument, which will be invoked with the future’s result when it resolves. If the coroutine fails, the callback will not be run and an exception will be raised into the surroundingStackContext
. Thecallback
argument is not visible inside the decorated function; it is handled by the decorator itself.From the caller’s perspective,
@gen.coroutine
is similar to the combination of@return_future
and@gen.engine
.Warning
When exceptions occur inside a coroutine, the exception information will be stored in the
Future
object. You must examine the result of theFuture
object, or the exception may go unnoticed by your code. This means yielding the function if called from another coroutine, using something likeIOLoop.run_sync
for top-level calls, or passing theFuture
toIOLoop.add_future
.
-
tornado.gen.
engine
(func)[source]¶ Callback-oriented decorator for asynchronous generators.
This is an older interface; for new code that does not need to be compatible with versions of Tornado older than 3.0 the
coroutine
decorator is recommended instead.This decorator is similar to
coroutine
, except it does not return aFuture
and thecallback
argument is not treated specially.In most cases, functions decorated with
engine
should take acallback
argument and invoke it with their result when they are finished. One notable exception is theRequestHandler
HTTP verb methods, which useself.finish()
in place of a callback argument.
Utility functions¶
-
exception
tornado.gen.
Return
(value=None)[source]¶ Special exception to return a value from a
coroutine
.If this exception is raised, its value argument is used as the result of the coroutine:
@gen.coroutine def fetch_json(url): response = yield AsyncHTTPClient().fetch(url) raise gen.Return(json_decode(response.body))
In Python 3.3, this exception is no longer necessary: the
return
statement can be used directly to return a value (previouslyyield
andreturn
with a value could not be combined in the same function).By analogy with the return statement, the value argument is optional, but it is never necessary to
raise gen.Return()
. Thereturn
statement can be used with no arguments instead.
-
tornado.gen.
with_timeout
(timeout, future, io_loop=None, quiet_exceptions=())[source]¶ Wraps a
Future
in a timeout.Raises
TimeoutError
if the input future does not complete beforetimeout
, which may be specified in any form allowed byIOLoop.add_timeout
(i.e. adatetime.timedelta
or an absolute time relative toIOLoop.time
)If the wrapped
Future
fails after it has timed out, the exception will be logged unless it is of a type contained inquiet_exceptions
(which may be an exception type or a sequence of types).Currently only supports Futures, not other
YieldPoint
classes.New in version 4.0.
Changed in version 4.1: Added the
quiet_exceptions
argument and the logging of unhandled exceptions.
-
tornado.gen.
maybe_future
(x)[source]¶ Converts
x
into aFuture
.If
x
is already aFuture
, it is simply returned; otherwise it is wrapped in a newFuture
. This is suitable for use asresult = yield gen.maybe_future(f())
when you don’t know whetherf()
returns aFuture
or not.
-
tornado.gen.
sleep
(duration)[source]¶ Return a
Future
that resolves after the given number of seconds.When used with
yield
in a coroutine, this is a non-blocking analogue totime.sleep
(which should not be used in coroutines because it is blocking):yield gen.sleep(0.5)
Note that calling this function on its own does nothing; you must wait on the
Future
it returns (usually by yielding it).New in version 4.1.
-
tornado.gen.
moment
¶ A special object which may be yielded to allow the IOLoop to run for one iteration.
This is not needed in normal use but it can be helpful in long-running coroutines that are likely to yield Futures that are ready instantly.
Usage:
yield gen.moment
New in version 4.0.
-
tornado.gen.
Task
(func, *args, **kwargs)[source]¶ Adapts a callback-based asynchronous function for use in coroutines.
Takes a function (and optional additional arguments) and runs it with those arguments plus a
callback
keyword argument. The argument passed to the callback is returned as the result of the yield expression.Changed in version 4.0:
gen.Task
is now a function that returns aFuture
, instead of a subclass ofYieldPoint
. It still behaves the same way when yielded.
-
class
tornado.gen.
WaitIterator
(*args, **kwargs)[source]¶ Provides an iterator to yield the results of futures as they finish.
Yielding a set of futures like this:
results = yield [future1, future2]
pauses the coroutine until both
future1
andfuture2
return, and then restarts the coroutine with the results of both futures. If either future is an exception, the expression will raise that exception and all the results will be lost.If you need to get the result of each future as soon as possible, or if you need the result of some futures even if others produce errors, you can use
WaitIterator
:wait_iterator = gen.WaitIterator(future1, future2) while not wait_iterator.done(): try: result = yield wait_iterator.next() except Exception as e: print "Error {} from {}".format(e, wait_iterator.current_future) else: print "Result {} recieved from {} at {}".format( result, wait_iterator.current_future, wait_iterator.current_index)
Because results are returned as soon as they are available the output from the iterator will not be in the same order as the input arguments. If you need to know which future produced the current result, you can use the attributes
WaitIterator.current_future
, orWaitIterator.current_index
to get the index of the future from the input list. (if keyword arguments were used in the construction of theWaitIterator
,current_index
will use the corresponding keyword).New in version 4.1.
-
class
tornado.gen.
Arguments
¶ The result of a
Task
orWait
whose callback had more than one argument (or keyword arguments).The
Arguments
object is acollections.namedtuple
and can be used either as a tuple(args, kwargs)
or an object with attributesargs
andkwargs
.
-
tornado.gen.
convert_yielded
(yielded)[source]¶ Convert a yielded object into a
Future
.The default implementation accepts lists, dictionaries, and Futures.
If the
singledispatch
library is available, this function may be extended to support additional types. For example:@convert_yielded.register(asyncio.Future) def _(asyncio_future): return tornado.platform.asyncio.to_tornado_future(asyncio_future)
New in version 4.1.
Legacy interface¶
Before support for Futures
was introduced in Tornado 3.0,
coroutines used subclasses of YieldPoint
in their yield
expressions.
These classes are still supported but should generally not be used
except for compatibility with older interfaces.
-
class
tornado.gen.
YieldPoint
[source]¶ Base class for objects that may be yielded from the generator.
Deprecated since version 4.0: Use
Futures
instead.-
start
(runner)[source]¶ Called by the runner after the generator has yielded.
No other methods will be called on this object before
start
.
-
-
class
tornado.gen.
Callback
(key)[source]¶ Returns a callable object that will allow a matching
Wait
to proceed.The key may be any value suitable for use as a dictionary key, and is used to match
Callbacks
to their correspondingWaits
. The key must be unique among outstanding callbacks within a single run of the generator function, but may be reused across different runs of the same function (so constants generally work fine).The callback may be called with zero or one arguments; if an argument is given it will be returned by
Wait
.Deprecated since version 4.0: Use
Futures
instead.
-
class
tornado.gen.
Wait
(key)[source]¶ Returns the argument passed to the result of a previous
Callback
.Deprecated since version 4.0: Use
Futures
instead.
-
class
tornado.gen.
WaitAll
(keys)[source]¶ Returns the results of multiple previous
Callbacks
.The argument is a sequence of
Callback
keys, and the result is a list of results in the same order.WaitAll
is equivalent to yielding a list ofWait
objects.Deprecated since version 4.0: Use
Futures
instead.