Typing Stubs for Paramiko
types-paramiko provides static type checking stubs for the Paramiko SSH library. It allows type checkers like Mypy and Pyright to analyze code that uses `paramiko` for better IDE support, type inference, and catching type-related errors before runtime. This package is part of the Typeshed project, aims to provide accurate annotations for `paramiko==4.0.*`, and is updated frequently, sometimes daily.
Warnings
- gotcha The `types-paramiko` package is designed to provide accurate type annotations for a specific major version of `paramiko` (e.g., `paramiko==4.0.*`). Using it with significantly older or newer `paramiko` versions may lead to incorrect type checking results or errors.
- gotcha Type stubs, especially for third-party libraries, can sometimes lag behind the runtime package. New features or API changes in `paramiko` might not immediately have corresponding type annotations in `types-paramiko`, leading to `mypy` or `pyright` reporting errors or missing type information.
- gotcha It is crucial to explicitly call `.close()` on `paramiko.SSHClient` and other connection objects when you are finished with them. Failing to do so can lead to resource leaks, hanging processes, or unexpected behavior at application shutdown, particularly in long-running applications or scripts.
- gotcha Paramiko is primarily designed to work with standard OpenSSH implementations. While it can connect to various SSH servers, issues might arise with non-Unix-like or proprietary SSH implementations (e.g., some Cisco devices, Windows SSH servers). These issues might not be prioritized for fixes unless a community-contributed patch is provided.
- gotcha Directly using `paramiko.SSHClient.exec_command()` for sequences of interactive commands or where output parsing depends on specific prompts can be unreliable. `exec_command` is best for single, non-interactive commands. Handling complex, interactive sessions requires managing input/output streams and parsing prompts manually, which is prone to race conditions and unreliability.
Install
-
pip install types-paramiko paramiko
Imports
- SSHClient
import paramiko client = paramiko.SSHClient()
- Transport
import paramiko transport = paramiko.Transport(...)
- PKey
import paramiko key = paramiko.PKey()
Quickstart
import paramiko
import os
import sys
def ssh_connect_and_execute(
hostname: str,
username: str,
command: str,
password: str = None,
port: int = 22
) -> str:
client = paramiko.SSHClient()
# Automatically add new host keys (use with caution in production)
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
# Load system host keys by default
client.load_system_host_keys()
if password:
client.connect(hostname, port=port, username=username, password=password, timeout=10)
else:
# Assumes an SSH agent is running or keys are in default locations
client.connect(hostname, port=port, username=username, timeout=10)
# Execute a command
stdin, stdout, stderr = client.exec_command(command)
output = stdout.read().decode().strip()
error = stderr.read().decode().strip()
if error:
print(f"Error executing command: {error}", file=sys.stderr)
return ""
return output
except paramiko.AuthenticationException:
print("Authentication failed, please verify your credentials (username/password/keys).", file=sys.stderr)
return ""
except paramiko.SSHException as e:
print(f"SSH connection or command execution failed: {e}", file=sys.stderr)
return ""
except Exception as e:
print(f"An unexpected error occurred: {e}", file=sys.stderr)
return ""
finally:
# Always close the client connection to prevent resource leaks
if client:
client.close()
if __name__ == "__main__":
# Example usage with environment variables
HOST = os.environ.get("SSH_HOST", "your_ssh_server.com")
USER = os.environ.get("SSH_USER", "your_username")
PASS = os.environ.get("SSH_PASSWORD", "") # Use SSH keys whenever possible
CMD = os.environ.get("SSH_COMMAND", "echo Hello from Paramiko!")
PORT = int(os.environ.get("SSH_PORT", 22))
if HOST == "your_ssh_server.com":
print("Please set SSH_HOST, SSH_USER, and optionally SSH_PASSWORD/SSH_PORT environment variables.", file=sys.stderr)
sys.exit(1)
print(f"Attempting to connect to {USER}@{HOST}:{PORT} and execute '{CMD}'")
result = ssh_connect_and_execute(HOST, USER, CMD, PASS if PASS else None, PORT)
if result:
print("\n--- Command Output ---")
print(result)
else:
print("\n--- Command execution failed ---", file=sys.stderr)