{"id":456,"library":"tornado","title":"Tornado","description":"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.","status":"active","version":"6.5.5","language":"python","source_language":"en","source_url":"https://github.com/tornadoweb/tornado","tags":["web framework","asynchronous","networking","Python"],"install":[{"cmd":"pip install tornado","lang":"bash","label":"Install Tornado"}],"dependencies":[{"reason":"Tornado integrates with asyncio for asynchronous programming","package":"asyncio","optional":false}],"imports":[{"note":"Ensure correct import path to avoid ImportError","symbol":"RequestHandler","correct":"from tornado.web import RequestHandler"},{"note":"Ensure correct import path to avoid ImportError","symbol":"Application","correct":"from tornado.web import Application"},{"note":"Ensure correct import path to avoid ImportError","symbol":"IOLoop","correct":"from tornado.ioloop import IOLoop"}],"quickstart":{"code":"import asyncio\nfrom tornado.web import Application, RequestHandler\nfrom tornado.ioloop import IOLoop\n\nclass MainHandler(RequestHandler):\n    def get(self):\n        self.write('Hello, world')\n\ndef make_app():\n    return Application([\n        (r'/', MainHandler),\n    ])\n\nasync def main():\n    app = make_app()\n    app.listen(8888)\n    await asyncio.Event().wait()\n\nif __name__ == '__main__':\n    asyncio.run(main())","lang":"python","description":"A simple Tornado application that responds with 'Hello, world' to GET requests on the root URL."},"warnings":[{"fix":"Replace IOLoop.add_callback_from_signal with asyncio.loop.add_signal_handler.","message":"IOLoop.add_callback_from_signal is deprecated and will be removed in Tornado 7.0. Use asyncio.loop.add_signal_handler instead.","severity":"breaking","affected_versions":"<=6.4.0"},{"fix":"Remove the client_secret argument from OAuth2Mixin.authorize_redirect calls.","message":"The client_secret argument to OAuth2Mixin.authorize_redirect is deprecated and will be removed in Tornado 7.0.","severity":"deprecated","affected_versions":"<=6.4.0"},{"fix":"Use IOLoop.add_callback to schedule callbacks on the main thread.","message":"Tornado is not thread-safe. Ensure that Tornado objects are not accessed from multiple threads simultaneously.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T13:56:24.817Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"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')`.","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.","error":"No handlers could be found for logger \"tornado.access\""},{"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.","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`.","error":"TypeError: 'generator' object is not awaitable"},{"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.","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.","error":"RuntimeError: Cannot run `IOLoop.run_sync` without a current IOLoop"},{"fix":"Import the specific submodule directly: `from tornado import web` or `import tornado.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.","error":"AttributeError: module 'tornado' has no attribute 'web'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":8.6,"disk_size":"21.1M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.29,"mem_mb":8.6,"disk_size":"22M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.41,"mem_mb":9.7,"disk_size":"23.9M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.33,"mem_mb":9.7,"disk_size":"24M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.57,"mem_mb":9.8,"disk_size":"15.6M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.56,"mem_mb":9.8,"disk_size":"16M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.59,"mem_mb":10,"disk_size":"15.2M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.53,"mem_mb":10,"disk_size":"16M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":8.4,"disk_size":"20.6M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":8.4,"disk_size":"21M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":-1},{"runtime":"python:3.10-slim","exit_code":-1},{"runtime":"python:3.11-alpine","exit_code":-1},{"runtime":"python:3.11-slim","exit_code":-1},{"runtime":"python:3.12-alpine","exit_code":-1},{"runtime":"python:3.12-slim","exit_code":-1},{"runtime":"python:3.13-alpine","exit_code":-1},{"runtime":"python:3.13-slim","exit_code":-1},{"runtime":"python:3.9-alpine","exit_code":-1},{"runtime":"python:3.9-slim","exit_code":-1}]}}