Skip to main content

High-performance SSH and SFTPclient for network automation

Project description

Jimiko

A high-performance SSH client for network automation and device management, built with libssh2. Inspired by Paramiko and Netmiko, but with a focus on performance and non-blocking operations.

Features

  • Non-blocking SSH operations for high performance
  • Support for interactive shell sessions
  • Configurable timeouts and interrupt handling
  • Cross-platform support (macOS, Linux, Rhel)
  • Python 3.6+ compatibility
  • Optimized for network device automation
  • Support legacy unauthenicated network devices
  • Built on libssh2 for maximum performance

Installation

Prerequisites Building from Source

Windows

# Using vcpkg
vcpkg install libssh2:x64-windows

macOS

# Using Homebrew
brew install libssh2

Linux (Debian/Ubuntu)

sudo apt-get install libssh2-1-dev

Linux (CentOS/RHEL)

sudo yum install libssh2-devel

Installing the Package

# No prerequisites required 
pip install jimiko

API Documentation

SSH Client (PyJimikoClient)

Constructor Parameters

Parameter Type Default Description
ip string Required IP address or hostname of the remote server
username string "" Username for authentication
password string "" Password for authentication
expected_prompt string "" Regex pattern to identify command completion
auth bool True Whether to use authentication
port int 22 SSH port number
command_timeout_ms uint32 30000 Command execution timeout in milliseconds
read_timeout_ms uint32 5000 Read operation timeout in milliseconds

Main Methods

Method Parameters Return Description
connect() None bool Establishes connection to the server
disconnect() None None Closes the connection
send(command, command_timeout_ms, read_timeout_ms) string, uint32, uint32 string Sends a command and returns output
get_initial_output(timeout_ms) uint32 string Captures initial banner output

PTY Options

When using shell connections, the SSH client uses a PTY (Pseudo Terminal) with type "vanilla". Other common terminal types include:

  • "vanilla" - Basic terminal
  • "vt100" - DEC VT100 terminal
  • "vt102" - DEC VT102 terminal
  • "vt220" - DEC VT220 terminal
  • "xterm" - X Window System terminal
  • "ansi" - ANSI terminal
  • "linux" - Linux console
  • "dumb" - Minimal terminal

SFTP Client (PyJimikoSFTPClient)

Constructor Parameters

Parameter Type Default Description
ip string Required IP address or hostname of the remote server
username string Required Username for authentication
password string Required Password for authentication
port int 22 SSH port number
operation_timeout_ms uint32 30000 Operation timeout in milliseconds

Main Methods

Method Parameters Return Description
connect() None bool Establishes SFTP connection
disconnect() None None Closes the connection
put(local_path, remote_path, mode) string, string, int bool Uploads file to remote server
get(remote_path, local_path) string, string bool Downloads file from remote server
list_dir(path) string vector Lists directory contents
file_exists(path) string bool Checks if file exists
file_info(path) string SFTPFileInfo Gets file information
make_dir(path, mode) string, int bool Creates a directory
remove_file(path) string bool Deletes a file
remove_dir(path) string bool Removes a directory
rename(old_path, new_path) string, string bool Renames a file or directory

Usage Examples

SSH Client (Authenticated)

from jimiko import PyJimikoClient

# Create SSH client with authentication
client = PyJimikoClient(
    ip="192.168.1.1",
    username="admin",
    password="password123",
    expected_prompt="[$#>]",  # Regex pattern for common prompts
    auth=True,
    port=22,
    command_timeout_ms=5000,   # 5 seconds command timeout
    read_timeout_ms=10000      # 10 seconds read timeout
)

# Connect to device
if client.connect():
    # Send commands
    result = client.send("show version")
    print(result)
    
    # Send command with custom timeout
    result = client.send("show tech-support", command_timeout_ms=60000)
    print(result)
    
    # Disconnect when done
    client.disconnect()

SSH Client (Non-Authenticated)

from jimiko import PyJimikoClient

# Create SSH client without authentication (for legacy devices)
client = PyJimikoClient(
    ip="192.168.1.2",
    auth=False,
    port=22
)

# Connect to device
if client.connect():
    # Get initial banner/login prompt
    initial_output = client.get_initial_output(timeout_ms=5000)
    print(initial_output)
    
    # Send login credentials manually if needed
    if "login:" in initial_output:
        result = client.send("admin")
        result = client.send("password123")
    
    # Now send commands as normal
    result = client.send("show interface")
    print(result)
    
    # Disconnect when done
    client.disconnect()

SFTP Client

from jimiko import PyJimikoSFTPClient
import os

# Create SFTP client
sftp = PyJimikoSFTPClient(
    ip="192.168.1.1",
    username="admin",
    password="password123",
    port=22,
    operation_timeout_ms=30000  # 30 second timeout
)

# Connect to server
if sftp.connect():
    # Upload a file (with mode 0644)
    sftp.put("local_file.txt", "/remote/path/file.txt", 0o644)
    
    # Download a file
    sftp.get("/remote/path/file.txt", "downloaded_file.txt")
    
    # List directory contents
    files = sftp.list_dir("/remote/path")
    for file_info in files:
        print(f"Name: {file_info.name}, Size: {file_info.size} bytes")
    
    # Check if file exists
    if sftp.file_exists("/remote/path/file.txt"):
        # Get file info
        info = sftp.file_info("/remote/path/file.txt")
        print(f"File size: {info.size}, Modified: {info.mtime}")
        
        # Create directory
        sftp.make_dir("/remote/path/new_dir", 0o755)
        
        # Rename file
        sftp.rename("/remote/path/file.txt", "/remote/path/new_file.txt")
        
        # Delete file
        sftp.remove_file("/remote/path/new_file.txt")
        
        # Remove directory
        sftp.remove_dir("/remote/path/new_dir")
    
    # Disconnect when done
    sftp.disconnect()

Why Jimiko?

Jimiko similar features of Paramiko and Netmiko with high-performance C++ implementation:

  • Performance: Built on libssh2 with C++ for maximum speed
  • Non-blocking: All operations are non-blocking by default
  • Timeouts: Fine-grained timeout control for all operations
  • Device Support: Special support for network devices including non-authenicated ssh sessions
  • Error Handling: Robust error handling with specific exceptions
  • Cross-Platform: macOS and Linux

Development Setup

  1. Clone the repository:
git clone https://github.com/jameshill/jimiko.git
cd jimiko
  1. Install development dependencies:
pip install -r requirements-dev.txt
  1. Build the extension:
python setup.py build_ext --inplace

Building from Source

Windows

# Set VCPKG_ROOT environment variable
# See github workflow
set VCPKG_ROOT=C:\vcpkg\installed\x64-windows
python setup.py build

macOS

Build locally on Mac.
bash
python setup.py build

License

MIT License

Contributing

  1. Fork the repository
  2. Create your feature branch
  3. Commit your changes
  4. Push to the branch
  5. Create a new Pull Request

Docker Build Environment for Jimiko

This directory contains a Docker-based build environment for compiling Jimiko with static linking of libssh2 and OpenSSL using manylinux-2014 compatibility.

Features

  • Based on Fedora 35 (producing binaries compatible with CentOS/Rhel)
  • Statically links libssh2 and OpenSSL with position independent code (-fPIC)
  • Produces portable binary wheels that work on Centos/Rhel systems
  • MacOS build locally
  • Ubuntu - wip

Prerequisites

  • Docker installed and running
  • Access to the Fedora Docker registry

Building the Docker Image

From the root of the project:

See ./docker/
Build Python 3.6-3.11 
./docker/build_sequential.sh 

Customizing the Build

The Docker image includes:

  • Modern GCC compiler from Fedora 35
  • OpenSSL 1.1.1w built from source with -fPIC
  • libssh2 1.11.0 built from source with -fPIC
  • Environment variables set for static linking

If you need to customize the build process:

  1. Modify the Dockerfile to install additional dependencies
  2. Adjust the build.sh script to change how the wheel is built
  3. Rebuild the Docker image with your changes

Troubleshooting

  • If you encounter issues with the static libraries, check that the paths in build.sh match the actual paths in the container.
  • Make sure your project is properly mounted as a volume in the container.
  • For debugging, you can run the container with an interactive shell and execute build steps manually.
  • For "dangerous relocation" errors when linking static libraries, ensure they were compiled with -fPIC.
  • If you experience linker issues with Python, ensure that the Python shared libraries are in the LD_LIBRARY_PATH.

What Gets Created

The build process creates several artifacts:

  1. A standard Python wheel in the dist/ directory
  2. A specific wheel with "-manylinux" in the filename (also in dist/)
  3. A platform-specific binary file in src/jimiko/ named _jimiko_wrapper.cpython-<python-version>-manylinux2024_x86_64.so

The extracted binary file is used when creating a universal wheel that includes binaries for multiple platforms.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jimiko-2.0.6rc9-py3-none-any.whl (37.0 MB view details)

Uploaded Python 3

File details

Details for the file jimiko-2.0.6rc9-py3-none-any.whl.

File metadata

  • Download URL: jimiko-2.0.6rc9-py3-none-any.whl
  • Upload date:
  • Size: 37.0 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for jimiko-2.0.6rc9-py3-none-any.whl
Algorithm Hash digest
SHA256 e0b0b15e625b5d6ec2a3e258cb13f906e38ac377f0fe6ef356f477170a70eaa4
MD5 750ad6100eef22c0cb5d2cd203b0e0bd
BLAKE2b-256 e1386398f8edc3d04818639d09fbbaec80697a0dc36c5e66012d1e4c30dd20cc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page