Terminado
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.
Warnings
- 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).
- 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).
- 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.
- 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.
- 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.
Install
-
pip install terminado tornado ptyprocess
Imports
- TermSocket
from terminado.websocket import TermSocket
- SingleTermManager
from terminado.management import SingleTermManager
- UniqueTermManager
from terminado.management import UniqueTermManager
- NamedTermManager
from terminado.management import NamedTermManager
Quickstart
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()