Skip to main content

Tornado

Tornado is a FriendFeed-developed Python web framework and asynchronous networking tool. Tornado can expand to tens of thousands of open connections utilising non-blocking network I/O, making it excellent for lengthy polling, WebSockets, and other applications that require a long-lived connection to each user.

Tornadoes can be categorised into four major categories:

  • A framework for the web (including RequestHandler which is subclassed to create web applications, and various supporting classes).
  • HTTP implementations on the client and server sides (HTTPServer and AsyncHTTPClient).
  • The classes IOLoop and IOStream, which serve as the building blocks for the HTTP components and can be be used to develop other protocols, are included in this asynchronous networking package.
  • tornado.gen is a coroutine package that makes writing asynchronous programming more straightforward than chaining callbacks. This is analogous to Python's native coroutine feature, which was introduced in version 3.5. (async def). When native coroutines are available, they should be used instead of the tornado.gen module.

For Tornado, here's a simple "Hello, world" sample web app:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")

def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])

if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()

Threads and WSGI

Tornado isn't like the other Python web frameworks. It is not dependent on WSGI, and each process is usually executed with only one thread. More information about Tornado's approach to asynchronous programming can be found in the User's Guide.

While the tornado.wsgi module provides some WSGI support, it is not a primary focus of development, and most applications should be designed to directly use Tornado's native interfaces (such as tornado.web) rather than WSGI.

In general, Tornado code is not thread-safe. The only method in Tornado that is safe to call from other threads is IOLoop.add_callback. You can also use IOLoop.run_in_executor to asynchronously run a blocking function on another thread, but note that the function passed to run_in_executor should avoid referencing any Tornado objects. run_in_executor is the recommended way to interact with blocking code.

asyncio Integration

Tornado is linked to the asyncio module in the standard library and uses the same event loop (by default since Tornado 5.0). Libraries created for asyncio can often be blended easily with Tornado.

Installation

pip install tornado

Tornado is a Python package that can be installed using pip. You may want to download a copy of the source tarball or clone the git repository as well because the source distribution includes demo programmes that aren't available when Tornado is installed this way.

Prerequisites:

Tornado 6.0 requires Python 3.5.2 or newer as a pre-requisite. Optional packages that may be useful include:

  • The optional tornado.curl_httpclient uses pycurl, and libcurl version 7.22 or higher is required.
  • tornado.platform.twisted classes can be used with Twisted.
  • pycares is a non-blocking DNS resolver that can be used when threads aren't acceptable.

Platforms:

Tornado is optimised for Unix-like platforms, providing the highest performance and scalability on systems that support epoll (Linux), kqueue (BSD/macOS), or /dev/poll (Windows) (Solaris).

Tornado can operate on Windows as well, albeit this is not officially supported or encouraged for production use. On Windows, some capabilities (such as multi-process mode) are missing, and scalability is limited (Even though Tornado is built on asyncio, which supports Windows, Tornado does not use the APIs that are necessary for scalable networking on Windows).