# Gotty Python Client
A generic Python client for interacting with gotty terminal interfaces.
## What is Gotty?
[Gotty](https://github.com/sorear/gotty) is a tool that turns terminal applications into web applications. It provides a WebSocket interface that allows you to interact with terminal applications through a web browser.
## Features
- **Generic gotty protocol support**: Works with any gotty terminal interface
- **WebSocket communication**: Real-time bidirectional communication
- **Authentication support**: Basic HTTP authentication
- **Command execution**: Send commands and receive responses
- **Terminal output buffering**: Maintains history of terminal output
- **Threading support**: Background message handling
- **Callback system**: Real-time output and command callbacks
## Security Considerations
⚠️ **IMPORTANT SECURITY WARNINGS**
This client has several security considerations you should be aware of:
1. **Insecure by Default**: The client uses unencrypted WebSocket connections (`ws://`) by default. For production use, ensure your gotty server supports secure WebSocket connections (`wss://`).
2. **Plain Text Credentials**: Credentials are stored and transmitted in plain text. Consider using environment variables or secure credential management.
3. **Command Injection**: The client sends commands directly to the terminal. Validate and sanitize all commands before sending them.
4. **Network Exposure**: This client can execute commands on remote systems. Use with caution and only connect to trusted servers.
5. **No Input Validation**: The client performs minimal input validation. Always validate URLs, usernames, and commands before use.
**Best Practices:**
- Use HTTPS/WSS connections in production
- Store credentials in environment variables
- Validate all inputs before use
- Only connect to trusted gotty servers
- Monitor and log all command executions
## Installation
```bash
pip install gotty-py
```
## Quick Start
```python
from gotty_py import GottyWebSocketClient
import os
# Create a client with environment variables for security
client = GottyWebSocketClient(
webui_url=os.getenv("GOTTY_URL", "http://localhost:8222"),
username=os.getenv("GOTTY_USERNAME", "admin"),
password=os.getenv("GOTTY_PASSWORD", "password")
)
# Connect to the gotty interface
if client.connect():
print("Connected successfully!")
# Execute a command
response = client.execute_command("ls -la")
if response.success:
print("Command output:", response.data)
# Close the connection
client.close()
```
## Usage
### Basic Connection
```python
from gotty_py import GottyWebSocketClient
import os
client = GottyWebSocketClient(
webui_url=os.getenv("GOTTY_URL", "http://your-server:port"),
username=os.getenv("GOTTY_USERNAME", "your_username"),
password=os.getenv("GOTTY_PASSWORD", "your_password")
)
# Connect
if client.connect():
print("Connected!")
else:
print("Connection failed!")
```
### Executing Commands
```python
# Execute a command and wait for response
response = client.execute_command("echo 'Hello, World!'")
if response.success:
print("Output:", response.data)
else:
print("Error:", response.message)
# Execute a command without waiting for response
response = client.execute_command("long_running_command", wait_for_response=False)
```
### Getting Terminal Output
```python
# Get all terminal output
output = client.get_terminal_output()
# Get last 10 lines
recent_output = client.get_terminal_output(last_n_lines=10)
# Get command history
history = client.get_command_history()
```
### Real-time Callbacks
```python
def on_output(data):
print(f"New output: {data}")
def on_command(cmd):
print(f"Command executed: {cmd}")
# Add callbacks
client.add_output_callback(on_output)
client.add_command_callback(on_command)
```
## API Reference
### GottyWebSocketClient
#### Constructor
```python
GottyWebSocketClient(
webui_url: str,
username: str,
password: str,
timeout: int = 30
)
```
#### Methods
- `connect() -> bool`: Connect to the gotty WebSocket interface
- `execute_command(command: str, wait_for_response: bool = True, timeout: float = 10.0) -> ServerResponse`: Execute a command
- `send_command(command: str) -> bool`: Send a command without waiting for response
- `get_terminal_output(last_n_lines: Optional[int] = None) -> List[str]`: Get terminal output
- `get_command_history() -> List[str]`: Get command history
- `add_output_callback(callback: Callable[[str], None])`: Add output callback
- `add_command_callback(callback: Callable[[str], None])`: Add command callback
- `close()`: Close the connection
### ServerResponse
```python
@dataclass
class ServerResponse:
success: bool
data: Any
message: str
status_code: int
```
## Examples
### Minecraft Server Integration
```python
from gotty_py import GottyWebSocketClient
# Connect to a Minecraft server with gotty
client = GottyWebSocketClient(
webui_url="http://minecraft-server:8222",
username="admin",
password="minecraft"
)
if client.connect():
# List players
response = client.execute_command("list")
if response.success:
print("Players:", response.data)
# Give items
client.execute_command("give player diamond_sword 1")
client.close()
```
### SSH Terminal
```python
from gotty_py import GottyWebSocketClient
# Connect to an SSH terminal via gotty
client = GottyWebSocketClient(
webui_url="http://ssh-server:8080",
username="user",
password="pass"
)
if client.connect():
# Run commands
client.execute_command("pwd")
client.execute_command("ls -la")
client.execute_command("whoami")
client.close()
```
## Development
### Installation for Development
```bash
git clone https://github.com/twentworth/gotty-py.git
cd gotty-py
pip install -e .
pip install -e ".[dev]"
```
### Running Tests
```bash
# Run unit tests only (safe for CI)
pytest -m "not integration"
# Run integration tests (requires real gotty server)
pytest -m "integration"
# Run all tests
pytest
```
**Note:** Integration tests require a real gotty server to be running. These tests are excluded from CI/CD pipelines since they need external infrastructure.
### Code Formatting
```bash
black .
```
### Type Checking
```bash
mypy .
```
## License
MIT License - see LICENSE file for details.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Raw data
{
"_id": null,
"home_page": "https://github.com/twentworth/gotty-py",
"name": "gotty-py",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "Thomas Wentworth <thomaswentworth@example.com>",
"keywords": "gotty, websocket, terminal, client, tty",
"author": "Thomas Wentworth",
"author_email": "Thomas Wentworth <thomaswentworth@example.com>",
"download_url": "https://files.pythonhosted.org/packages/f2/32/135db37c27d0c379e76cd8d0e45136f43fa1c1c858a6e47e9c94edcda69c/gotty_py-1.0.2.tar.gz",
"platform": null,
"description": "# Gotty Python Client\n\nA generic Python client for interacting with gotty terminal interfaces.\n\n## What is Gotty?\n\n[Gotty](https://github.com/sorear/gotty) is a tool that turns terminal applications into web applications. It provides a WebSocket interface that allows you to interact with terminal applications through a web browser.\n\n## Features\n\n- **Generic gotty protocol support**: Works with any gotty terminal interface\n- **WebSocket communication**: Real-time bidirectional communication\n- **Authentication support**: Basic HTTP authentication\n- **Command execution**: Send commands and receive responses\n- **Terminal output buffering**: Maintains history of terminal output\n- **Threading support**: Background message handling\n- **Callback system**: Real-time output and command callbacks\n\n## Security Considerations\n\n\u26a0\ufe0f **IMPORTANT SECURITY WARNINGS**\n\nThis client has several security considerations you should be aware of:\n\n1. **Insecure by Default**: The client uses unencrypted WebSocket connections (`ws://`) by default. For production use, ensure your gotty server supports secure WebSocket connections (`wss://`).\n\n2. **Plain Text Credentials**: Credentials are stored and transmitted in plain text. Consider using environment variables or secure credential management.\n\n3. **Command Injection**: The client sends commands directly to the terminal. Validate and sanitize all commands before sending them.\n\n4. **Network Exposure**: This client can execute commands on remote systems. Use with caution and only connect to trusted servers.\n\n5. **No Input Validation**: The client performs minimal input validation. Always validate URLs, usernames, and commands before use.\n\n**Best Practices:**\n- Use HTTPS/WSS connections in production\n- Store credentials in environment variables\n- Validate all inputs before use\n- Only connect to trusted gotty servers\n- Monitor and log all command executions\n\n## Installation\n\n```bash\npip install gotty-py\n```\n\n## Quick Start\n\n```python\nfrom gotty_py import GottyWebSocketClient\nimport os\n\n# Create a client with environment variables for security\nclient = GottyWebSocketClient(\n webui_url=os.getenv(\"GOTTY_URL\", \"http://localhost:8222\"),\n username=os.getenv(\"GOTTY_USERNAME\", \"admin\"),\n password=os.getenv(\"GOTTY_PASSWORD\", \"password\")\n)\n\n# Connect to the gotty interface\nif client.connect():\n print(\"Connected successfully!\")\n \n # Execute a command\n response = client.execute_command(\"ls -la\")\n if response.success:\n print(\"Command output:\", response.data)\n \n # Close the connection\n client.close()\n```\n\n## Usage\n\n### Basic Connection\n\n```python\nfrom gotty_py import GottyWebSocketClient\nimport os\n\nclient = GottyWebSocketClient(\n webui_url=os.getenv(\"GOTTY_URL\", \"http://your-server:port\"),\n username=os.getenv(\"GOTTY_USERNAME\", \"your_username\"),\n password=os.getenv(\"GOTTY_PASSWORD\", \"your_password\")\n)\n\n# Connect\nif client.connect():\n print(\"Connected!\")\nelse:\n print(\"Connection failed!\")\n```\n\n### Executing Commands\n\n```python\n# Execute a command and wait for response\nresponse = client.execute_command(\"echo 'Hello, World!'\")\nif response.success:\n print(\"Output:\", response.data)\nelse:\n print(\"Error:\", response.message)\n\n# Execute a command without waiting for response\nresponse = client.execute_command(\"long_running_command\", wait_for_response=False)\n```\n\n### Getting Terminal Output\n\n```python\n# Get all terminal output\noutput = client.get_terminal_output()\n\n# Get last 10 lines\nrecent_output = client.get_terminal_output(last_n_lines=10)\n\n# Get command history\nhistory = client.get_command_history()\n```\n\n### Real-time Callbacks\n\n```python\ndef on_output(data):\n print(f\"New output: {data}\")\n\ndef on_command(cmd):\n print(f\"Command executed: {cmd}\")\n\n# Add callbacks\nclient.add_output_callback(on_output)\nclient.add_command_callback(on_command)\n```\n\n## API Reference\n\n### GottyWebSocketClient\n\n#### Constructor\n\n```python\nGottyWebSocketClient(\n webui_url: str,\n username: str,\n password: str,\n timeout: int = 30\n)\n```\n\n#### Methods\n\n- `connect() -> bool`: Connect to the gotty WebSocket interface\n- `execute_command(command: str, wait_for_response: bool = True, timeout: float = 10.0) -> ServerResponse`: Execute a command\n- `send_command(command: str) -> bool`: Send a command without waiting for response\n- `get_terminal_output(last_n_lines: Optional[int] = None) -> List[str]`: Get terminal output\n- `get_command_history() -> List[str]`: Get command history\n- `add_output_callback(callback: Callable[[str], None])`: Add output callback\n- `add_command_callback(callback: Callable[[str], None])`: Add command callback\n- `close()`: Close the connection\n\n### ServerResponse\n\n```python\n@dataclass\nclass ServerResponse:\n success: bool\n data: Any\n message: str\n status_code: int\n```\n\n## Examples\n\n### Minecraft Server Integration\n\n```python\nfrom gotty_py import GottyWebSocketClient\n\n# Connect to a Minecraft server with gotty\nclient = GottyWebSocketClient(\n webui_url=\"http://minecraft-server:8222\",\n username=\"admin\",\n password=\"minecraft\"\n)\n\nif client.connect():\n # List players\n response = client.execute_command(\"list\")\n if response.success:\n print(\"Players:\", response.data)\n \n # Give items\n client.execute_command(\"give player diamond_sword 1\")\n \n client.close()\n```\n\n### SSH Terminal\n\n```python\nfrom gotty_py import GottyWebSocketClient\n\n# Connect to an SSH terminal via gotty\nclient = GottyWebSocketClient(\n webui_url=\"http://ssh-server:8080\",\n username=\"user\",\n password=\"pass\"\n)\n\nif client.connect():\n # Run commands\n client.execute_command(\"pwd\")\n client.execute_command(\"ls -la\")\n client.execute_command(\"whoami\")\n \n client.close()\n```\n\n## Development\n\n### Installation for Development\n\n```bash\ngit clone https://github.com/twentworth/gotty-py.git\ncd gotty-py\npip install -e .\npip install -e \".[dev]\"\n```\n\n### Running Tests\n\n```bash\n# Run unit tests only (safe for CI)\npytest -m \"not integration\"\n\n# Run integration tests (requires real gotty server)\npytest -m \"integration\"\n\n# Run all tests\npytest\n```\n\n**Note:** Integration tests require a real gotty server to be running. These tests are excluded from CI/CD pipelines since they need external infrastructure.\n\n### Code Formatting\n\n```bash\nblack .\n```\n\n### Type Checking\n\n```bash\nmypy .\n```\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A generic Python client for interacting with gotty terminal interfaces",
"version": "1.0.2",
"project_urls": {
"Bug Tracker": "https://github.com/twentworth/gotty-py/issues",
"Changelog": "https://github.com/twentworth/gotty-py/blob/main/CHANGELOG.md",
"Documentation": "https://github.com/twentworth/gotty-py#readme",
"Homepage": "https://github.com/twentworth/gotty-py",
"Repository": "https://github.com/twentworth/gotty-py.git"
},
"split_keywords": [
"gotty",
" websocket",
" terminal",
" client",
" tty"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "95ec261f1009aa88ca8000f23678e499914285a17dce6cea0c1f33a8edadde8d",
"md5": "8bb59ce06736f27b39cf28200af2a5b1",
"sha256": "7222363ba27f19bcc153833df4d2f97be48fc1a26e1b38704b2291f76717535e"
},
"downloads": -1,
"filename": "gotty_py-1.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8bb59ce06736f27b39cf28200af2a5b1",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 9372,
"upload_time": "2025-08-13T23:50:53",
"upload_time_iso_8601": "2025-08-13T23:50:53.251804Z",
"url": "https://files.pythonhosted.org/packages/95/ec/261f1009aa88ca8000f23678e499914285a17dce6cea0c1f33a8edadde8d/gotty_py-1.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f232135db37c27d0c379e76cd8d0e45136f43fa1c1c858a6e47e9c94edcda69c",
"md5": "4e0988783245e73ad672f89f0a7e8d64",
"sha256": "213a25c6884d4f55f6daefbec9b524f46c132e86ea3f4dc2f500a2c34baf119f"
},
"downloads": -1,
"filename": "gotty_py-1.0.2.tar.gz",
"has_sig": false,
"md5_digest": "4e0988783245e73ad672f89f0a7e8d64",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 14054,
"upload_time": "2025-08-13T23:50:54",
"upload_time_iso_8601": "2025-08-13T23:50:54.349663Z",
"url": "https://files.pythonhosted.org/packages/f2/32/135db37c27d0c379e76cd8d0e45136f43fa1c1c858a6e47e9c94edcda69c/gotty_py-1.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-13 23:50:54",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "twentworth",
"github_project": "gotty-py",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "websockets",
"specs": [
[
">=",
"11.0.3"
]
]
},
{
"name": "requests",
"specs": [
[
">=",
"2.31.0"
]
]
},
{
"name": "pytest",
"specs": [
[
">=",
"7.4.2"
]
]
},
{
"name": "pytest-cov",
"specs": [
[
">=",
"4.1.0"
]
]
},
{
"name": "black",
"specs": [
[
">=",
"23.7.0"
]
]
},
{
"name": "mypy",
"specs": [
[
">=",
"1.5.1"
]
]
},
{
"name": "flake8",
"specs": [
[
">=",
"6.0.0"
]
]
},
{
"name": "isort",
"specs": [
[
">=",
"5.12.0"
]
]
}
],
"lcname": "gotty-py"
}