# Ananta (formerly Hydra)
Ananta is a *powerful* command-line tool designed to simplify simultaneous SSH command execution across multiple remote hosts. It enhances workflows, automates repetitive tasks, and improves efficiency for system administrators and developers managing distributed systems.
## Namesake
Ananta draws inspiration from Ananta Shesha or Ananta Nagaraja (อนันตนาคราช), the many-headed serpentine demigod from Hindu mythology deeply rooted in Thai culture.
Initially, this project was named Hydra, referencing the many-headed serpent in Greek mythology. However, due to the abundance of projects named Hydra or hydra-* on PyPI (e.g., the previous project at [https://pypi.org/project/hydra-ssh/](https://pypi.org/project/hydra-ssh/)), it was renamed to Ananta. The commands you now use are `ananta`, which is shorter, more distinctive, and easier to remember than `hydra-ssh`.
## Features
- Concurrent execution of commands across multiple remote hosts
- Flexible host list configuration in **TOML** or **CSV** format
- SSH authentication with public key support
- Lightweight and user-friendly command-line interface
- Interactive Text User Interface (TUI) for real-time command execution and output viewing
- Color-coded output for easy host differentiation
- Option to separate host outputs for clarity
- [non-TUI mode] Support for cursor control codes for specific layouts (e.g., `fastfetch`, `neofetch`)
## Installation
### System Requirements
- Python 3.10 or higher
- `pip` package manager
- Required dependencies: `asyncssh`, `argparse`, `asyncio`, `urwid` (for TUI mode)
- Optional: `uvloop` (Unix-based systems) or `winloop` (Windows) for enhanced performance
- For TOML host files on Python 3.10: `tomli` (automatically installed)
### Installing via pip
Install Ananta using pip:
```bash
pip install ananta --user
```
Install Ananta with `uvloop` or `winloop` for *speed* enhancement:
```bash
pip install ananta[speed] --user
```
**Note:** Ensure Python 3.10 or higher is installed. For TOML host files, Python 3.10 requires `tomli`, while Python 3.11 and above use the built-in `tomllib`. If you previously used `hydra-ssh`, update to `pip install ananta` to get the latest version. The `urwid` library is automatically installed for TUI mode support.
## Usage
### Hosts File Format
Ananta supports host files in **TOML** or **CSV** format, allowing flexible configuration of remote hosts. Below are the structures for each format.
***Note:** The TOML format is recommended for its clarity and ease of use. Any hosts file without `.toml` extension will be treated as a CSV file.*
#### TOML Host File
Create a TOML file with a `[default]` section (optional) and host sections. Example:
```toml
[default]
port = 22
username = "user"
key_path = "#"
tags = ["common"]
[host-1]
ip = "10.0.0.1"
port = 2222
key_path = "/home/user/.ssh/id_ed25519"
[host-2]
ip = "10.0.0.2"
tags = ["web"]
[host-3]
ip = "10.0.0.3"
tags = ["arch", "web"]
["host-4"]
ip = "10.0.0.4"
tags = ["ubuntu", "db"]
```
- **[default] Section**:
- Optional section to set default values for `port`, `username`, `key_path`, and `tags`.
- `key_path` can be `#` to use the default SSH key which can be specified via `-k` or common keys in `~/.ssh/`.
- Fields not specified in a host section will use these defaults (except `ip`, which is required).
- `tags`: Default tags applied to all hosts, appended to host-specific tags.
- **Host Sections**:
- Each section (e.g., `[host-1]`) defines a host with the following fields to override defaults:
- `ip`: Required IP address or resolvable hostname
- `port`: SSH port
- `username`: SSH username
- `key_path`: Path to SSH private key
- `tags`: Optional list of tags (e.g., `["web", "prod"]`)
- **Tags**:
- Tags from `[default]` are *appended* to tags specified in each host section.
- For example, if `default.tags = ["common"]` and `host-3.tags = ["arch", "web"]`, `host-3` will have tags `["common", "arch", "web"]`.
- Use the `-t` option to filter hosts by tags (e.g., `-t common,web` matches hosts with any of these tags).
- **Note**: TOML parsing requires `tomli` on Python 3.10 (included in Ananta's dependencies) or `tomllib` on Python 3.11 and above.
#### CSV Host File
Create a CSV file with the following structure:
```csv
#alias,ip,port,username,key_path,tags(optional - colon separated)
host-1,10.0.0.1,2222,user,/home/user/.ssh/id_ed25519
host-2,10.0.0.2,22,user,#,web
host-3,10.0.0.3,22,user,#,arch:web
host-4,10.0.0.4,22,user,#,ubuntu:db
```
- Lines starting with `#` are ignored.
- **Fields**:
- `alias`: Unique name for the host
- `ip`: IP address or resolvable hostname
- `port`: SSH port number
- `username`: SSH username
- `key_path`: Path to SSH private key, or `#` to use the default key (via `-k` or common keys in `~/.ssh/`)
- `tags`: Optional tags, separated by colons (e.g., `web:db`)
- **Tags**: Used for filtering hosts with the `-t` option (e.g., `-t web,db`).
### Running Commands
Run commands on remote hosts with:
```bash
ananta <options> [hosts file] [command]
```
**Examples:**
```console
# Run 'uptime' on all hosts in a CSV hosts file
$ ananta hosts.csv uptime
# Run 'sensors' with separate output on all hosts in a CSV hosts file
$ ananta -s host.csv sensors
# Run 'fastfetch' with cursor control enabled and separate output on all hosts in a TOML hosts file
$ ananta -cs hosts.toml fastfetch
# Filter hosts by tags 'web' or 'db' (CSV hosts file)
$ ananta -t web,db hosts.csv uptime
# Filter hosts by tags 'common' or 'web' (TOML hosts file, includes default tags)
$ ananta -t common,web hosts.toml uptime
# Update Arch Linux hosts (TOML hosts file)
$ ananta -t arch hosts.toml sudo pacman -Syu --noconfirm
```
### Text User Interface (TUI) Mode
Ananta provides an interactive Text User Interface (TUI) powered by the `urwid` library, allowing real-time command input and output viewing across multiple remote hosts. The TUI mode is ideal for interactive sessions where you want to monitor command outputs as they stream in.
**Launching TUI Mode:**
Launch the TUI with the `--tui` flag:
```bash
ananta --tui [hosts file] [initial command]
```
**Examples:**
```console
# Launch TUI with a TOML hosts file and no initial command
$ ananta --tui hosts.toml
# Launch TUI with a CSV hosts file and run 'uptime' initially
$ ananta --tui hosts.csv uptime
# Launch TUI with tag filtering and an initial command
$ ananta --tui -t web,db hosts.toml "df -h"
```
**Using the TUI:**
- **Input Prompt**: At the `>>>` prompt, type commands to execute on all connected hosts.
- **Output Display**: Outputs from each host are displayed with color-coded host names for clarity.
- **Navigation**: Use the arrow keys or mouse to scroll through the output.
- **Exit**: Type `exit` or press `Ctrl+C` or `Ctrl+D` to quit the TUI.
- **Options**: Supports `-t` (host tags), `-k` (default key), `-s` (separate output), and `-e` (allow empty lines) as in non-TUI mode. Note that `-n` (no-color), `-w` (terminal width), and `-c` (cursor control) are ignored in TUI mode, as the TUI handles these internally.
**Notes:**
- Requires the `urwid` library, automatically installed with `pip install ananta`.
- The TUI mode streams output in real-time for interleaved display or waits for complete output with `-s` (separate output).
- Cursor control codes are stripped to ensure proper rendering in the TUI.
### Options
**Single-letter options are case-insensitive.**
- `-n, --no-color`: Disable colorized output
- `-s, --separate-output`: Display output from each host separately
- `-t, --host-tags`: Filter hosts by tag(s), comma-separated (e.g., `web,db`)
- `-w, --terminal-width`: Manually set terminal width
- `-e, --allow-empty-line`: Permit printing of empty lines
- `-c, --allow-cursor-control`: Enable cursor control codes (e.g., for `fastfetch` or `neofetch`)
- `-v, --version`: Display the Ananta version
- `-k, --default-key`: Specify the default SSH private key
- `--tui`: Launch the Text User Interface (TUI) mode
### Demo
[](https://asciinema.org/a/711115)
[](https://asciinema.org/a/711116)
## Contributing
We welcome contributions to Ananta! Whether you're fixing bugs, adding features, or improving docs, check out our [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to get started.
## [License](LICENSE)
Raw data
{
"_id": null,
"home_page": "https://github.com/cwt/ananta",
"name": "ananta",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": null,
"author": "Chaiwat Suttipongsakul",
"author_email": "cwt@bashell.com",
"download_url": "https://files.pythonhosted.org/packages/10/52/40aa0ef46932b8100cf0643e07e4d3f739f3f69c3053a750ab9b9f897caa/ananta-1.3.6.tar.gz",
"platform": null,
"description": "# Ananta (formerly Hydra)\n\nAnanta is a *powerful* command-line tool designed to simplify simultaneous SSH command execution across multiple remote hosts. It enhances workflows, automates repetitive tasks, and improves efficiency for system administrators and developers managing distributed systems.\n\n## Namesake\n\nAnanta draws inspiration from Ananta Shesha or Ananta Nagaraja (\u0e2d\u0e19\u0e31\u0e19\u0e15\u0e19\u0e32\u0e04\u0e23\u0e32\u0e0a), the many-headed serpentine demigod from Hindu mythology deeply rooted in Thai culture.\n\nInitially, this project was named Hydra, referencing the many-headed serpent in Greek mythology. However, due to the abundance of projects named Hydra or hydra-* on PyPI (e.g., the previous project at [https://pypi.org/project/hydra-ssh/](https://pypi.org/project/hydra-ssh/)), it was renamed to Ananta. The commands you now use are `ananta`, which is shorter, more distinctive, and easier to remember than `hydra-ssh`.\n\n## Features\n\n- Concurrent execution of commands across multiple remote hosts\n- Flexible host list configuration in **TOML** or **CSV** format\n- SSH authentication with public key support\n- Lightweight and user-friendly command-line interface\n- Interactive Text User Interface (TUI) for real-time command execution and output viewing\n- Color-coded output for easy host differentiation\n- Option to separate host outputs for clarity\n- [non-TUI mode] Support for cursor control codes for specific layouts (e.g., `fastfetch`, `neofetch`)\n\n## Installation\n\n### System Requirements\n\n- Python 3.10 or higher\n- `pip` package manager\n- Required dependencies: `asyncssh`, `argparse`, `asyncio`, `urwid` (for TUI mode)\n- Optional: `uvloop` (Unix-based systems) or `winloop` (Windows) for enhanced performance\n- For TOML host files on Python 3.10: `tomli` (automatically installed)\n\n### Installing via pip\n\nInstall Ananta using pip:\n\n```bash\npip install ananta --user\n```\n\nInstall Ananta with `uvloop` or `winloop` for *speed* enhancement:\n\n```bash\npip install ananta[speed] --user\n```\n\n**Note:** Ensure Python 3.10 or higher is installed. For TOML host files, Python 3.10 requires `tomli`, while Python 3.11 and above use the built-in `tomllib`. If you previously used `hydra-ssh`, update to `pip install ananta` to get the latest version. The `urwid` library is automatically installed for TUI mode support.\n\n## Usage\n\n### Hosts File Format\n\nAnanta supports host files in **TOML** or **CSV** format, allowing flexible configuration of remote hosts. Below are the structures for each format.\n***Note:** The TOML format is recommended for its clarity and ease of use. Any hosts file without `.toml` extension will be treated as a CSV file.*\n\n#### TOML Host File\n\nCreate a TOML file with a `[default]` section (optional) and host sections. Example:\n\n```toml\n[default]\nport = 22\nusername = \"user\"\nkey_path = \"#\"\ntags = [\"common\"]\n\n[host-1]\nip = \"10.0.0.1\"\nport = 2222\nkey_path = \"/home/user/.ssh/id_ed25519\"\n\n[host-2]\nip = \"10.0.0.2\"\ntags = [\"web\"]\n\n[host-3]\nip = \"10.0.0.3\"\ntags = [\"arch\", \"web\"]\n\n[\"host-4\"]\nip = \"10.0.0.4\"\ntags = [\"ubuntu\", \"db\"]\n```\n\n- **[default] Section**:\n - Optional section to set default values for `port`, `username`, `key_path`, and `tags`.\n - `key_path` can be `#` to use the default SSH key which can be specified via `-k` or common keys in `~/.ssh/`.\n - Fields not specified in a host section will use these defaults (except `ip`, which is required).\n - `tags`: Default tags applied to all hosts, appended to host-specific tags.\n- **Host Sections**:\n - Each section (e.g., `[host-1]`) defines a host with the following fields to override defaults:\n - `ip`: Required IP address or resolvable hostname\n - `port`: SSH port\n - `username`: SSH username\n - `key_path`: Path to SSH private key\n - `tags`: Optional list of tags (e.g., `[\"web\", \"prod\"]`)\n- **Tags**:\n - Tags from `[default]` are *appended* to tags specified in each host section.\n - For example, if `default.tags = [\"common\"]` and `host-3.tags = [\"arch\", \"web\"]`, `host-3` will have tags `[\"common\", \"arch\", \"web\"]`.\n - Use the `-t` option to filter hosts by tags (e.g., `-t common,web` matches hosts with any of these tags).\n- **Note**: TOML parsing requires `tomli` on Python 3.10 (included in Ananta's dependencies) or `tomllib` on Python 3.11 and above.\n\n#### CSV Host File\n\nCreate a CSV file with the following structure:\n\n```csv\n#alias,ip,port,username,key_path,tags(optional - colon separated)\nhost-1,10.0.0.1,2222,user,/home/user/.ssh/id_ed25519\nhost-2,10.0.0.2,22,user,#,web\nhost-3,10.0.0.3,22,user,#,arch:web\nhost-4,10.0.0.4,22,user,#,ubuntu:db\n```\n\n- Lines starting with `#` are ignored.\n- **Fields**:\n - `alias`: Unique name for the host\n - `ip`: IP address or resolvable hostname\n - `port`: SSH port number\n - `username`: SSH username\n - `key_path`: Path to SSH private key, or `#` to use the default key (via `-k` or common keys in `~/.ssh/`)\n - `tags`: Optional tags, separated by colons (e.g., `web:db`)\n- **Tags**: Used for filtering hosts with the `-t` option (e.g., `-t web,db`).\n\n### Running Commands\n\nRun commands on remote hosts with:\n\n```bash\nananta <options> [hosts file] [command]\n```\n\n**Examples:**\n\n```console\n# Run 'uptime' on all hosts in a CSV hosts file\n$ ananta hosts.csv uptime\n\n# Run 'sensors' with separate output on all hosts in a CSV hosts file\n$ ananta -s host.csv sensors\n\n# Run 'fastfetch' with cursor control enabled and separate output on all hosts in a TOML hosts file\n$ ananta -cs hosts.toml fastfetch\n\n# Filter hosts by tags 'web' or 'db' (CSV hosts file)\n$ ananta -t web,db hosts.csv uptime\n\n# Filter hosts by tags 'common' or 'web' (TOML hosts file, includes default tags)\n$ ananta -t common,web hosts.toml uptime\n\n# Update Arch Linux hosts (TOML hosts file)\n$ ananta -t arch hosts.toml sudo pacman -Syu --noconfirm\n```\n\n### Text User Interface (TUI) Mode\n\nAnanta provides an interactive Text User Interface (TUI) powered by the `urwid` library, allowing real-time command input and output viewing across multiple remote hosts. The TUI mode is ideal for interactive sessions where you want to monitor command outputs as they stream in.\n\n**Launching TUI Mode:**\n\nLaunch the TUI with the `--tui` flag:\n\n```bash\nananta --tui [hosts file] [initial command]\n```\n\n**Examples:**\n\n```console\n# Launch TUI with a TOML hosts file and no initial command\n$ ananta --tui hosts.toml\n\n# Launch TUI with a CSV hosts file and run 'uptime' initially\n$ ananta --tui hosts.csv uptime\n\n# Launch TUI with tag filtering and an initial command\n$ ananta --tui -t web,db hosts.toml \"df -h\"\n```\n\n**Using the TUI:**\n\n- **Input Prompt**: At the `>>>` prompt, type commands to execute on all connected hosts.\n- **Output Display**: Outputs from each host are displayed with color-coded host names for clarity.\n- **Navigation**: Use the arrow keys or mouse to scroll through the output.\n- **Exit**: Type `exit` or press `Ctrl+C` or `Ctrl+D` to quit the TUI.\n- **Options**: Supports `-t` (host tags), `-k` (default key), `-s` (separate output), and `-e` (allow empty lines) as in non-TUI mode. Note that `-n` (no-color), `-w` (terminal width), and `-c` (cursor control) are ignored in TUI mode, as the TUI handles these internally.\n\n**Notes:**\n\n- Requires the `urwid` library, automatically installed with `pip install ananta`.\n- The TUI mode streams output in real-time for interleaved display or waits for complete output with `-s` (separate output).\n- Cursor control codes are stripped to ensure proper rendering in the TUI.\n\n### Options\n\n**Single-letter options are case-insensitive.**\n\n- `-n, --no-color`: Disable colorized output\n- `-s, --separate-output`: Display output from each host separately\n- `-t, --host-tags`: Filter hosts by tag(s), comma-separated (e.g., `web,db`)\n- `-w, --terminal-width`: Manually set terminal width\n- `-e, --allow-empty-line`: Permit printing of empty lines\n- `-c, --allow-cursor-control`: Enable cursor control codes (e.g., for `fastfetch` or `neofetch`)\n- `-v, --version`: Display the Ananta version\n- `-k, --default-key`: Specify the default SSH private key\n- `--tui`: Launch the Text User Interface (TUI) mode\n\n### Demo\n\n[](https://asciinema.org/a/711115)\n\n[](https://asciinema.org/a/711116)\n\n## Contributing\n\nWe welcome contributions to Ananta! Whether you're fixing bugs, adding features, or improving docs, check out our [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to get started.\n\n## [License](LICENSE)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A command-line tool to execute commands on multiple remote hosts",
"version": "1.3.6",
"project_urls": {
"Homepage": "https://github.com/cwt/ananta",
"Repository": "https://github.com/cwt/ananta",
"Sourcehut Mirror": "https://sr.ht/~cwt/ananta/"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "170005247648d2154b20616c46adbf93f7abcfec2f17b96bda426e0a2e52f3bb",
"md5": "442698e211f62efc7a18cd0664b00829",
"sha256": "3a36aa0fb737eeadd8e89368a296cc6188178cbdbd89bf864be911ea530942bb"
},
"downloads": -1,
"filename": "ananta-1.3.6-py3-none-any.whl",
"has_sig": false,
"md5_digest": "442698e211f62efc7a18cd0664b00829",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 24677,
"upload_time": "2025-08-09T11:33:05",
"upload_time_iso_8601": "2025-08-09T11:33:05.015306Z",
"url": "https://files.pythonhosted.org/packages/17/00/05247648d2154b20616c46adbf93f7abcfec2f17b96bda426e0a2e52f3bb/ananta-1.3.6-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "105240aa0ef46932b8100cf0643e07e4d3f739f3f69c3053a750ab9b9f897caa",
"md5": "c0bf3cfabfece341e1d05704d48d1ac0",
"sha256": "6e7d0dc280863d8d57eefafd2a083c18d70fe7f14cb433a3c7cfdf0b3eaf3503"
},
"downloads": -1,
"filename": "ananta-1.3.6.tar.gz",
"has_sig": false,
"md5_digest": "c0bf3cfabfece341e1d05704d48d1ac0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 24520,
"upload_time": "2025-08-09T11:33:06",
"upload_time_iso_8601": "2025-08-09T11:33:06.377100Z",
"url": "https://files.pythonhosted.org/packages/10/52/40aa0ef46932b8100cf0643e07e4d3f739f3f69c3053a750ab9b9f897caa/ananta-1.3.6.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-09 11:33:06",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "cwt",
"github_project": "ananta",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "ananta"
}