Tornado

raw JSON →
6.5.5 verified Tue May 12 auth: no python install: verified quickstart: stale

Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. It enables scalable, non-blocking network I/O, making it ideal for applications requiring long-lived connections, such as long polling and WebSockets. The current version is 6.5.5, with a release cadence of approximately every few months.

pip install tornado
error No handlers could be found for logger "tornado.access"
cause Tornado's default access logger tries to log HTTP requests but no logging handlers are configured in the Python standard logging library for the 'tornado.access' logger.
fix
Configure Python's logging system to add a handler, for example: import logging; logging.basicConfig(level=logging.INFO) or configure specific handlers for logging.getLogger('tornado.access').
error TypeError: 'generator' object is not awaitable
cause This error typically occurs in Python 3.5+ when an `async def` function uses the `yield` keyword instead of `await`, or when an object that is a generator (e.g., from `@tornado.gen.coroutine` without proper conversion) is passed to `await`.
fix
Replace yield with await in async def functions, and ensure all asynchronous operations return awaitable objects (e.g., futures, coroutines). If using old @tornado.gen.coroutine code, consider converting it to async def or ensure it's called using yield from in compatible contexts.
error RuntimeError: Cannot run `IOLoop.run_sync` without a current IOLoop
cause `IOLoop.run_sync()` is called from a context (e.g., a new thread or script without a Tornado application running) where no `IOLoop` has been initialized or set as the current IOLoop for that thread.
fix
Ensure IOLoop.current() is available and initialized in the execution context where run_sync is called. If running async code from a synchronous entry point, start the IOLoop first, e.g., IOLoop.current().start() or IOLoop.current().run_sync(your_async_function) within an already running IOLoop's context.
error AttributeError: module 'tornado' has no attribute 'web'
cause This happens when the `tornado` package is imported generally (e.g., `import tornado`), but submodules like `web` are then accessed as direct attributes of the `tornado` module, which is incorrect.
fix
Import the specific submodule directly: from tornado import web or import tornado.web.
breaking IOLoop.add_callback_from_signal is deprecated and will be removed in Tornado 7.0. Use asyncio.loop.add_signal_handler instead.
fix Replace IOLoop.add_callback_from_signal with asyncio.loop.add_signal_handler.
deprecated The client_secret argument to OAuth2Mixin.authorize_redirect is deprecated and will be removed in Tornado 7.0.
fix Remove the client_secret argument from OAuth2Mixin.authorize_redirect calls.
gotcha Tornado is not thread-safe. Ensure that Tornado objects are not accessed from multiple threads simultaneously.
fix Use IOLoop.add_callback to schedule callbacks on the main thread.
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.28s 21.1M
3.10 slim (glibc) - - 0.29s 22M
3.11 alpine (musl) - - 0.41s 23.9M
3.11 slim (glibc) - - 0.33s 24M
3.12 alpine (musl) - - 0.57s 15.6M
3.12 slim (glibc) - - 0.56s 16M
3.13 alpine (musl) - - 0.59s 15.2M
3.13 slim (glibc) - - 0.53s 16M
3.9 alpine (musl) - - 0.23s 20.6M
3.9 slim (glibc) - - 0.20s 21M

A simple Tornado application that responds with 'Hello, world' to GET requests on the root URL.

import asyncio
from tornado.web import Application, RequestHandler
from tornado.ioloop import IOLoop

class MainHandler(RequestHandler):
    def get(self):
        self.write('Hello, world')

def make_app():
    return Application([
        (r'/', MainHandler),
    ])

async def main():
    app = make_app()
    app.listen(8888)
    await asyncio.Event().wait()

if __name__ == '__main__':
    asyncio.run(main())