WebTerm
A fully-featured web-based terminal using Python/FastAPI backend with real-time WebSocket communication and xterm.js frontend.
Features
- Full Terminal Emulation: Complete terminal experience with xterm.js
- Real-time Communication: WebSocket-based bidirectional communication
- Multiple Themes: Catppuccin Mocha/Latte, Dracula, Nord, Tokyo Night
- System Monitoring: Live CPU, memory, and GPU usage in header
- Detailed Stats Panel: Picture-in-picture panel with per-core CPU, memory breakdown, and top processes
- File Explorer: Browse, upload, and download files
- Clipboard Support: Ctrl+Shift+C/V and right-click context menu
- Mouse Support: Full mouse event passthrough for terminal applications
- Token Authentication: Optional token-based authentication via environment variable
- Cross-Platform: Works on macOS and Linux
Installation
# Clone the repository
git clone https://github.com/abhishekkrthakur/webterm.git
cd webterm
# Install dependencies
pip install -e .
Usage
Basic Usage
# Start the server (localhost only by default)
webterm
# Open http://127.0.0.1:8000 in your browser
Command Line Options
webterm [OPTIONS]
Options:
--host TEXT Host to bind to [default: 127.0.0.1]
--port INTEGER Port to bind to [default: 8000]
--reload Enable auto-reload for development
--help Show this message and exit
With Authentication
# Set a token for authentication
export WEBTERM_TOKEN="your-secret-token"
webterm
# Users will need to enter the token to access the terminal
Configuration
WebTerm can be configured via environment variables (prefix: WEBTERM_):
| Variable | Default | Description |
|---|---|---|
WEBTERM_HOST |
127.0.0.1 |
Host to bind to |
WEBTERM_PORT |
8000 |
Port to bind to |
WEBTERM_SHELL |
User's shell | Shell to use (e.g., /bin/zsh) |
WEBTERM_MAX_SESSIONS |
10 |
Maximum concurrent sessions |
WEBTERM_SESSION_TIMEOUT |
3600 |
Session timeout in seconds |
WEBTERM_LOG_LEVEL |
INFO |
Log level |
WEBTERM_TOKEN |
None | Authentication token (enables auth if set) |
You can also use a .env file in the working directory.
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
Ctrl+Shift+C |
Copy selection |
Ctrl+Shift+V |
Paste from clipboard |
| Right-click | Context menu (copy/paste) |
API Endpoints
WebSocket
GET /ws/terminal- WebSocket endpoint for terminal communication- Query param
tokenor cookiewebterm_authfor authentication
- Query param
REST API
GET /- Terminal HTML pageGET /health- Health checkGET /api/files?path=<path>- List files in directoryGET /api/files/download?path=<path>- Download a filePOST /api/files/upload?path=<path>- Upload files (multipart/form-data)
Authentication
GET /auth/login- Login pagePOST /auth/login- Login with tokenPOST /auth/logout- Logout
WebSocket Protocol
Client → Server
{"type": "input", "data": "ls -la\r"}
{"type": "resize", "rows": 30, "cols": 120}
{"type": "get_cwd"}
Server → Client
{"type": "output", "data": "...terminal output..."}
{"type": "stats", "cpu": 25.5, "memory": 60.2, "gpu": 30.0, "gpu_name": "Apple M1"}
{"type": "cwd", "path": "/home/user/projects"}
{"type": "error", "message": "Session terminated"}
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Browser Client │
│ xterm.js Terminal ◄──► WebSocket Client ◄──► Terminal UI │
└───────────────────────────────┬─────────────────────────────────┘
│ WebSocket (bidirectional)
▼
┌─────────────────────────────────────────────────────────────────┐
│ FastAPI Backend │
│ Static Files │ WebSocket Endpoint │ REST API Endpoints │
│ │ │
│ Terminal Session Manager │
│ │ │
│ PTY Manager (pty module) │
└─────────────────────────┬───────────────────────────────────────┘
▼
Shell Process (bash/zsh)
Project Structure
src/webterm/
├── api/
│ ├── app.py # FastAPI application factory
│ ├── auth.py # Authentication logic
│ ├── websocket.py # WebSocket connection manager
│ └── routes/
│ ├── auth.py # Auth routes
│ ├── files.py # File explorer routes
│ ├── health.py # Health check
│ └── terminal.py # Terminal routes
├── cli/
│ └── webterm.py # CLI entry point
├── core/
│ ├── config.py # Pydantic Settings
│ ├── pty_manager.py # PTY handling
│ ├── session.py # Session management
│ └── stats.py # System stats collection
├── static/
│ ├── css/
│ │ └── terminal.css # Styles (Catppuccin theme)
│ └── js/
│ └── terminal.js # xterm.js client
└── templates/
└── index.html # Main HTML page
Security Considerations
- Localhost by default: Binds to 127.0.0.1 to prevent external access
- Token authentication: Optional but recommended for any network exposure
- Session limits: Maximum concurrent sessions and timeout
- Secure cookies: HttpOnly, SameSite=Strict for auth cookies
- Timing-safe comparison: Uses
secrets.compare_digestfor token verification
Warning: This application provides shell access. Only expose to trusted networks and always use authentication when binding to non-localhost addresses.
Development
# Install in development mode
pip install -e ".[dev]"
# Run with auto-reload
webterm --reload
# Run linting
flake8 src/
Release files for webterm 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| webterm-0.0.2.tar.gz | 48.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| webterm-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 93.6 kB
Release files / webterm-0.0.2.tar.gz
| Download URL | webterm-0.0.2.tar.gz |
|---|---|
| Size | 48.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
568cfffa20ef060812ece768a5562be6514fd37c3d5f379739f0ce4c72fe0dd9
|
|
BLAKE2b-256 checksum How to use checksums |
29ec31c49245008d8da0fcb0ae8b78010363b31c90a70b74fd21bc0f7499a93d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.11
|
Release files / webterm-0.0.2-py3-none-any.whl
| Download URL | webterm-0.0.2-py3-none-any.whl |
|---|---|
| Size | 44.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aead447a0b5287c2ceedef9893445e074f7436e64645e87754d2c89836923d8a
|
|
BLAKE2b-256 checksum How to use checksums |
44404a0ab213879a13b269ccde878dfd3b5d8f2a58ed7c5f18c469e18042d440
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.11
|