parallel-ssh (pssh)
parallel-ssh, imported as `pssh`, is an asynchronous Python library for executing commands and transferring files over SSH to multiple hosts in parallel. It leverages `asyncio` for high-performance operations, making it suitable for managing large clusters or performing fast, concurrent remote tasks. The current version is 2.16.0.post1, and it maintains a relatively active release cadence with minor updates every few months.
Common errors
-
ModuleNotFoundError: No module named 'parallel_ssh'
cause The PyPI package `parallel-ssh` is imported as the `pssh` Python module.fixChange your import statements from `import parallel_ssh` (or similar) to `import pssh` or `from pssh.clients import ParallelSSHClient`. -
TypeError: object NoneType can't be used in 'await' expression
cause `parallel-ssh` clients are asynchronous and their methods (e.g., `run_command`, `put_file`) must be `await`ed.fixEnsure you are calling `parallel-ssh` methods with the `await` keyword within an `async` function, and that your main script is run via `asyncio.run()`. -
[Errno -1] Authentication failed (or similar SSH authentication error messages like 'Permission denied')
cause Incorrect SSH credentials (username, password, private key path), wrong private key passphrase, or issues with host key verification (`known_hosts`).fixVerify the `user`, `password`, `pkey`, and `passphrase` arguments passed to your `SSHClient` or `ParallelSSHClient`. Ensure target hosts' public keys are correctly added to your `~/.ssh/known_hosts` file, or consider explicitly disabling strict host key checking for development (not recommended for production). -
RuntimeWarning: Enable asyncio debug mode to show full stack traces.
cause This is a common warning from `asyncio` when debug mode is not enabled, not an error specific to `parallel-ssh`. It indicates that `asyncio` will not provide full stack traces, which can make debugging harder.fixTo enable debug mode, set the environment variable `PYTHONASYNCIODEBUG=1` before running your script, or call `asyncio.get_event_loop().set_debug(True)` early in your program.
Warnings
- breaking Python 3.8+ is now required. Support for Python versions prior to 3.8 was dropped in `parallel-ssh` version 2.13.0.
- gotcha `SSHClient.disconnect()` is a no-op since version 2.14.0. Individual `SSHClient` instances now manage their own disconnection upon de-allocation.
- gotcha Compression is opt-in. As of version 2.15.0, `parallel-ssh` supports compression, but it is not enabled by default for clients.
- gotcha The PyPI package `parallel-ssh` installs as the `pssh` Python module. Attempting to import `parallel_ssh` will result in a `ModuleNotFoundError`.
Install
-
pip install parallel-ssh
Imports
- ParallelSSHClient
from parallel_ssh.clients import ParallelSSHClient
from pssh.clients import ParallelSSHClient
- SSHClient
from parallel_ssh.clients import SSHClient
from pssh.clients import SSHClient
Quickstart
import asyncio
from pssh.clients import ParallelSSHClient
import os
async def run_remote_commands():
# Replace with your actual hostnames or IP addresses
hosts = ['hostname1', 'hostname2']
# You can specify username, password, or private key path
# client = ParallelSSHClient(hosts, user='myuser', password=os.environ.get('SSH_PASSWORD', ''))
# client = ParallelSSHClient(hosts, user='myuser', pkey='/path/to/id_rsa')
client = ParallelSSHClient(hosts, user=os.environ.get('SSH_USER', 'your_user'))
print(f"Connecting to {hosts} and running 'ls -l /tmp'...")
output = await client.run_command('ls -l /tmp')
async for host_output in output:
print(f"\n--- Host: {host_output.host} ---")
print(f"Return Code: {host_output.return_code}")
print("Stdout:")
for line in host_output.stdout:
print(f" {line}")
print("Stderr:")
for line in host_output.stderr:
print(f" {line}")
if __name__ == '__main__':
# Ensure your SSH_USER env var is set or replace 'your_user' directly
# Also, ensure SSH agents or known_hosts are configured for passwordless access
# or provide password/pkey arguments to ParallelSSHClient.
asyncio.run(run_remote_commands())