Terminado

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

Terminado is a Tornado websocket backend for the Xterm.js Javascript terminal emulator library. It enables web applications to embed interactive terminal sessions by exposing a shell (like bash or cmd.exe) over WebSockets. The library is currently at version 0.18.1 and receives regular maintenance and upkeep releases, typically focusing on dependency updates and minor bug fixes.

pip install terminado tornado ptyprocess
error ModuleNotFoundError: No module named 'terminado'
cause The 'terminado' package has not been installed in the Python environment where the code is being executed.
fix
Install the 'terminado' library using pip: pip install terminado
error WebSocket connection to 'ws://localhost:8888/terminals/websocket/1' failed: HTTP error: status 404
cause The Tornado web application is not correctly configured to route WebSocket connections to the 'terminado.TerminalWebsocket' handler, often due to an incorrect URL pattern or handler registration.
fix
Ensure the 'TerminalWebsocket' handler is properly added to your 'tornado.web.Application' routes with the correct path, for example:
from tornado.web import Application
from terminado import TerminalWebsocket

def make_app():
    return Application([
        (r"/terminals/websocket/(.*)", TerminalWebsocket, {'shell_command': ['bash']}),
    ])
error ImportError: cannot import name 'TerminalWebsocket' from 'terminado'
cause The class name 'TerminalWebsocket' (or 'TermManager') is misspelled, or an attempt is made to import it from an incorrect submodule path, or the 'terminado' version is incompatible with the import statement.
fix
Ensure the class name is spelled correctly and imported directly from the top-level 'terminado' package (as of version 0.18.1):
from terminado import TerminalWebsocket, TermManager
error bash: command not found (or 'Permission denied' in the terminal output in browser)
cause The 'shell_command' configured for the 'terminado' handler refers to an executable that does not exist at the specified path, is not in the system's PATH, or lacks execution permissions on the server.
fix
Verify the 'shell_command' points to a valid and executable shell on your system. Use an absolute path if the command is not in the system's PATH, for example:
# For Linux/macOS
shell_command=['/bin/bash']
# For Windows
shell_command=['cmd.exe']
# Or for PowerShell on Windows
# shell_command=['powershell.exe']
breaking Python 3.7 support was removed in version 0.18.0. Users on Python 3.7 or older must upgrade their Python environment or use an older `terminado` version (<=0.17.x).
fix Upgrade Python to 3.8 or higher. If unable to upgrade Python, pin `terminado` to `<0.18.0`.
breaking Python 3.6 support was officially dropped in version 0.13.0. Users on Python 3.6 must upgrade their Python environment or use an older `terminado` version (<=0.12.x).
fix Upgrade Python to 3.7 or higher. If unable to upgrade Python, pin `terminado` to `<0.13.0`.
gotcha The `TermSocket` handler does not implement any authentication or authorization by default. Exposing it directly (especially with a shell command) without proper security measures allows anyone who can connect to run arbitrary commands on the server. This is a significant security risk.
fix Subclass `terminado.TermSocket` and override the `get` method to integrate with your application's authentication system (e.g., as shown in Jupyter's `IPythonHandler` example). Ensure only authenticated and authorized users can access the websocket endpoint. Listen only on `localhost` unless explicitly needed and secured.
gotcha Terminado is a *backend* library. It provides the server-side Python component for a terminal, but requires a client-side JavaScript terminal emulator (such as Xterm.js) to provide a complete interactive terminal experience in a web browser. The Python library does not include a GUI itself.
fix Integrate a JavaScript frontend library (e.g., Xterm.js) into your web application and configure it to connect to the `TermSocket` WebSocket endpoint provided by Terminado.
gotcha Older versions of Terminado (prior to 0.16.0) had a bug where large stdin writes could cause the Tornado server to hang, leading to unresponsive terminals.
fix Upgrade `terminado` to version 0.16.0 or newer to benefit from the fix for this issue. Ensure your application handles large inputs gracefully.
breaking Tests for `terminado` are timing out when run with Python 3.13. This may indicate a new compatibility issue specific to Python 3.13 that causes the library to hang or perform unacceptably slowly, leading to test failures.
fix Investigate `terminado`'s compatibility with Python 3.13. This might require updating `terminado` to a version explicitly supporting Python 3.13 or pinning to an older Python version (e.g., 3.12) if a compatible `terminado` version is not available.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.32s 21.4M
3.10 alpine (musl) - - 0.33s 21.4M
3.10 slim (glibc) wheel 1.8s 0.26s 22M
3.10 slim (glibc) - - 0.28s 22M
3.11 alpine (musl) wheel - 0.44s 24.2M
3.11 alpine (musl) - - 0.48s 24.2M
3.11 slim (glibc) wheel 1.9s 0.39s 25M
3.11 slim (glibc) - - 0.37s 25M
3.12 alpine (musl) wheel - 0.61s 15.8M
3.12 alpine (musl) - - 0.66s 15.8M
3.12 slim (glibc) wheel 1.8s 0.63s 16M
3.12 slim (glibc) - - 0.69s 16M
3.13 alpine (musl) wheel - 0.66s 15.5M
3.13 alpine (musl) - - 0.65s 15.4M
3.13 slim (glibc) wheel 1.9s 0.57s 16M
3.13 slim (glibc) - - 0.66s 16M
3.9 alpine (musl) wheel - 0.29s 20.9M
3.9 alpine (musl) - - 0.35s 20.9M
3.9 slim (glibc) wheel 2.2s 0.25s 21M
3.9 slim (glibc) - - 0.25s 21M

This quickstart sets up a basic Tornado web application with a `TermSocket` handler. It creates a single terminal instance managed by `SingleTermManager` and exposes it over a WebSocket endpoint. A simple HTTP handler is also included for initial access. Note that a client-side JavaScript terminal emulator (like Xterm.js) is required to interact with this backend. The `TERMINADO_SHELL`, `PORT`, and `HOST` environment variables can be used to customize the shell, port, and host respectively.

import os.path
import tornado.web
import tornado.ioloop
from terminado.websocket import TermSocket
from terminado.management import SingleTermManager

# NOTE: For a full web demo with a client-side terminal, you would also need
# tornado_xstatic and XStatic-term.js, and a corresponding HTML template.
# This example focuses on the Python server-side setup.

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello from Terminado server!\n")
        self.write("To use, connect a WebSocket-based terminal client (e.g., Xterm.js) to ws://localhost:8765/websocket")

if __name__ == "__main__":
    # Use 'bash' for Linux/macOS or 'cmd.exe' for Windows
    shell_command = os.environ.get('TERMINADO_SHELL', 'bash' if os.name != 'nt' else 'cmd.exe')
    term_manager = SingleTermManager(shell_command=[shell_command])

    handlers = [
        (r"/websocket", TermSocket, {"term_manager": term_manager}),
        (r"/", MainHandler),
    ]

    app = tornado.web.Application(handlers)
    port = int(os.environ.get('PORT', 8765))
    host = os.environ.get('HOST', 'localhost') # Listen on localhost for security
    app.listen(port, host)
    print(f"Terminado server started on http://{host}:{port}")
    print(f"WebSocket endpoint at ws://{host}:{port}/websocket")
    print(f"Using shell: {shell_command}")
    print("Press Ctrl+C to stop.")
    try:
        tornado.ioloop.IOLoop.current().start()
    except KeyboardInterrupt:
        print("\nServer stopped.")
    finally:
        term_manager.shutdown()