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']

Changed in version 3.2: Dict support added.

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 the return 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 the return statement without a value.

Functions with this decorator return a Future. Additionally, they may be called with a callback 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 surrounding StackContext. The callback 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 the Future object, or the exception may go unnoticed by your code. This means yielding the function if called from another coroutine, using something like IOLoop.run_sync for top-level calls, or passing the Future to IOLoop.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 a Future and the callback argument is not treated specially.

In most cases, functions decorated with engine should take a callback argument and invoke it with their result when they are finished. One notable exception is the RequestHandler HTTP verb methods, which use self.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 (previously yield and return 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(). The return statement can be used with no arguments instead.

tornado.gen.with_timeout(timeout, future, io_loop=None)[source]

Wraps a Future in a timeout.

Raises TimeoutError if the input future does not complete before timeout, which may be specified in any form allowed by IOLoop.add_timeout (i.e. a datetime.timedelta or an absolute time relative to IOLoop.time)

Currently only supports Futures, not other YieldPoint classes.

New in version 4.0.

exception tornado.gen.TimeoutError[source]

Exception raised by with_timeout.

tornado.gen.maybe_future(x)[source]

Converts x into a Future.

If x is already a Future, it is simply returned; otherwise it is wrapped in a new Future. This is suitable for use as result = yield gen.maybe_future(f()) when you don’t know whether f() returns a Future or not.

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 a Future, instead of a subclass of YieldPoint. It still behaves the same way when yielded.

class tornado.gen.Arguments

The result of a Task or Wait whose callback had more than one argument (or keyword arguments).

The Arguments object is a collections.namedtuple and can be used either as a tuple (args, kwargs) or an object with attributes args and kwargs.

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.

is_ready()[source]

Called by the runner to determine whether to resume the generator.

Returns a boolean; may be called more than once.

get_result()[source]

Returns the value to use as the result of the yield expression.

This method will only be called once, and only after is_ready has returned true.

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 corresponding Waits. 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 of Wait objects.

Deprecated since version 4.0: Use Futures instead.