Skip to main content

TurboSSH — SSH / Serial / SFTP / SCP / FTP / RDP terminal & automation toolkit for automotive & embedded (Python API, CLI, and a full PyQt5 GUI with a VT100 terminal).

Project description

TurboSSH

PyPI Python

TurboSSH is an SSH / Serial / SFTP / SCP / FTP / RDP terminal and automation toolkit built on Paramiko — for automotive & embedded work, test automation, and everyday remote ops. It ships three ways in one install:

  1. Python APIimport turbossh for scripts and test frameworks.
  2. CLIturbossh …, fully argument-driven.
  3. GUIturbossh-gui, a tabbed multi-session terminal with a true VT100 emulator (htop / vim / top work), an SFTP browser, serial consoles, and RDP launch. Ships as a prebuilt Windows exe (PyQt5 baked in — no PyQt5 install needed, even on Windows ARM64).
pip install turbossh
turbossh-gui

Table of contents

Install

pip install turbossh           # API + CLI + prebuilt Windows GUI exe
pip install "turbossh[gui]"    # also installs PyQt5 to run the GUI from source

Batteries included: paramiko, scp, pyserial, keyring, pywinrm, and pyte (VT100) are pulled in automatically. Only PyQt5 is optional — the shipped GUI exe already contains it, so turbossh-gui works without installing PyQt5.

The GUI

turbossh-gui
  • Session manager sidebar — saved SSH / Serial / RDP sessions (right-click for New / Open / Edit / Duplicate / Delete). Passwords live in the OS credential vault, never in plaintext. A Quick connect box filters as you type.
  • Tabbed sessions + a + button; Split tiles several sessions in a grid.
  • True VT100 terminal (pyte) — full-screen apps (htop, vim, top, less, nano) render correctly, with colors, a block cursor, and live PTY resize.
  • Quick buttons — one-click slog2info -w, journalctl -f, dmesg -w, tail -f, plus Ctrl-C and Clear.
  • Split SFTP browser under each terminal — navigate, upload, download, mkdir, rename, delete (transfers on a separate channel; the UI never blocks).
  • Serial console and RDP launch as session types.
  • Settings — dark/light theme, terminal font + size, default baud (persisted, applied live). MultiExec broadcasts a command to all open SSH tabs.
  • Crash-proof — all I/O on background threads; a startup failure shows a popup and writes a crash log; runtime errors are logged, never fatal.

Quick start (API)

from turbossh import SSHHandler, SSHConfig

with SSHHandler(SSHConfig(host="10.0.0.5", username="root", password="pw")) as ssh:
    print(ssh.run("uname -a").text)            # clean single-line output
    ssh.run("systemctl restart nginx", check=True)
    ssh.push("local.txt", "/tmp/remote.txt")
    ssh.pull("/etc/nginx", "./backup", recursive=True)

Connecting — local, jump host, RDP

# direct
cfg = SSHConfig(host="10.0.0.5", username="root", password="pw",
                host_key_policy="ignore")          # ignore = lab/reimaged devices

# through a bastion/jump (laptop -> jump -> target)
jump = SSHConfig(host="10.232.9.22", domain="CORP", username="user", password="pw")
cfg  = SSHConfig(host="10.120.1.91", username="root", password="pw", jump_host=jump)
host_key_policy Behaviour
"auto" (default) add unknown keys, reject changed keys
"ignore" accept any key incl. changed — for reimaged/DHCP lab devices
"reject" strict; only keys already in known_hosts

Auth is auto-selected: password, private key (+ passphrase), agent / discovered keys, empty-password accounts, or passwordless=True. Connects retry with backoff and reconnect automatically; a failed connect self-diagnoses (probes the SSH/RDP ports and explains why).

Running commands

r = ssh.run("ls -la", timeout=30, check=False)
print(r.text, r.exit_code, r.ok, r.duration)
ssh.run_many(["a", "b", "c"], stop_on_error=True)
ssh.sudo("systemctl restart app", password="pw")
with ssh.open_shell() as sh:                    # interactive send/expect
    sh.send("cd /var/log"); print(sh.read_until("$", timeout=5).output)

Continuous logs

ssh.stream("slog2info -w", on_line=print,
           match=r"error|fail", save_to="device.log", timeout=120)  # ANSI auto-cleaned
for line in ssh.iter_lines("journalctl -f"):
    print(line)

File transfer — SFTP / SCP / FTP

ssh.push("fw.bin", "/tmp/fw.bin")                 # SFTP upload
ssh.pull("/var/log/messages", "messages.log")     # SFTP download
ssh.push("./build", "/tmp/build", recursive=True) # folder, progress callback
ssh.scp_push("img.tar", "/tmp/img.tar")           # SCP protocol

from turbossh import FTPHandler, FTPConfig
with FTPHandler(FTPConfig(host="ftp.x", username="u", password="p", use_tls=True)) as ftp:
    ftp.push("a.txt", "a.txt"); ftp.pull("b.txt", "b.txt")

Through a jump host, transfers ride the tunnel automatically. Remote FS helpers: listdir, stat, exists, isdir, mkdir, makedirs, rename, remove, chmod, read_text, write_text, walk.

Serial / COM ports

# local port (device plugged into THIS machine)
from turbossh import SerialHandler, list_serial_ports
print(list_serial_ports())
with SerialHandler("COM5", baudrate=115200) as ser:
    ser.write_line("version")
    ser.stream(on_line=print, match=r"login:", save_to="com5.log")

# port on a REMOTE machine, over SSH/jump (COM = Windows, /dev/tty* = Linux)
ssh.serial_write("COM5", "version", baudrate=115200)
ssh.serial_stream("COM5", baudrate=115200, on_line=print, match=r"login:",
                  save_to="com5.log")

Port forwarding (tunnels)

# ssh -L : reach a remote service on a local port (e.g. a web UI behind the host)
fwd = ssh.forward_local("127.0.0.1", 8080, local_port=18080)
print("now browse http://127.0.0.1:%d" % fwd.local_port)
fwd.close()

# ssh -R : expose a local service on a remote port
rfwd = ssh.forward_remote(9000, "127.0.0.1", 3000)
rfwd.close()

Both work through a jump host and return a handle with .close() (or use as a context manager).

Keys & passwordless setup

from turbossh import generate_keypair
generate_keypair("~/.ssh/turbo_key")          # writes turbo_key and turbo_key.pub

# deploy it (ssh-copy-id) so future logins are passwordless
ssh.copy_id(public_key_file="~/.ssh/turbo_key.pub")

Automotive / legacy devices

Old ECUs / embedded SSH servers often use crypto modern Paramiko drops. Re-enable it:

cfg = SSHConfig(host="10.0.0.9", username="root", password="pw",
                enable_legacy_algorithms=True)     # old KEX/ciphers/host-keys
# fine-grained: disabled_algorithms={"pubkeys": ["rsa-sha2-512"]}

In the GUI, tick "Enable legacy algorithms" in the session dialog.

Confidential credentials

Mechanism What it does
Secret wraps a password; logs/reprs show ********; only .reveal() exposes it
mask() redacts secrets from any string (applied to all logging automatically)
CredentialStore stores/reads passwords in the OS vault via keyring — no plaintext
prompt_password() hidden terminal input

Enable SSH on a Windows box (offline)

turbossh-setup            # self-elevates, installs OpenSSH Server from a bundled
                          # ZIP (ARM64/Win64/Win32), starts sshd, opens firewall,
                          # generates + fixes host keys. No internet / Windows Update.

Or auto-enable a remote box over WinRM: SSHConfig(auto_bootstrap_via_winrm=True).

CLI reference

turbossh run    --host H --user U [--domain CORP] [--use-stored] uname -a
turbossh push   --host H --user U ./build /tmp/build --recursive
turbossh pull   --host H --user U /var/log ./logs --recursive
turbossh info   --host H --user U --json
turbossh store-credential --user U --domain CORP --service my_lab
turbossh-gui              # launch the GUI
turbossh-setup            # install OpenSSH Server on this machine (offline)
turbossh-shortcut         # create a Desktop shortcut to the GUI
turbossh-docs             # open the docs

Result objects & error handling

  • CommandResult.exit_code, .stdout, .text, .stderr, .duration, .ok
  • TransferResult.size_bytes, .duration, .human_speed, .files
  • OperationResult — safe-mode wrapper: bool(res), .value, .error, .unwrap()

Raise mode (default): typed exceptions — SSHConnectionError, SSHAuthenticationError, SSHTimeoutError, SSHCommandError, SSHTransferError, FTPError, SerialError, WinRMError, CredentialError (all subclass SSHError).

Safe mode (SSHHandler(cfg, safe=True)): every call returns an OperationResult instead of raising — ideal for GUIs and long-running tools.

Full Paramiko capability

TurboSSH wraps the common operations with retries, structured results, and safe secrets — but it never hides Paramiko. Anything Paramiko can do is available:

  • Commands / shellsrun, run_many, sudo, open_shell, stream, iter_lines
  • SFTP — full file operations + recursive push/pull with progress
  • SCPscp_push / scp_pull
  • Port forwardingforward_local (-L), forward_remote (-R)
  • Keysgenerate_keypair, copy_id (ssh-copy-id)
  • Jump host / ProxyJumpSSHConfig(jump_host=…)
  • Algorithm controlenable_legacy_algorithms, disabled_algorithms
  • Keepalives, compression, timeouts, host-key policy — all on SSHConfig
  • Raw escape hatchssh.client (the paramiko.SSHClient) and ssh.transport (the paramiko.Transport) are exposed, so any lower-level Paramiko call works:
transport = ssh.transport
sftp = ssh.client.open_sftp()
chan = transport.open_session()
# …anything Paramiko supports

API map

turbossh/
  config.py        SSHConfig (jump, legacy algos, host-key policy…), FTPConfig
  core.py          SSHHandler  (SSH + SFTP + SCP + stream + serial + tunnels +
                                keys + diagnose), ShellSession
  tunnel.py        LocalForward, RemoteForward, generate_keypair
  serial_handler.py  SerialHandler, list_serial_ports
  ftp.py           FTPHandler (FTP/FTPS)
  winrm_bootstrap.py  enable_openssh_via_winrm
  pool.py          SSHPool (parallel multi-host)
  credentials.py   Secret, CredentialStore, mask, prompt_password
  results.py       CommandResult, TransferResult, ShellResult, OperationResult
  cli.py           CLI + launchers (gui / docs / setup / shortcut / rdp)
  pyqt_worker.py   SSHWorker (embed in your own PyQt5 app)
  bin/turbossh-gui.exe   prebuilt GUI (PyQt5 baked in)
  gui/             the desktop app
    vt100.py       true VT100 terminal (pyte) — htop/vim render correctly
    sftp_browser.py · session_widgets.py · session_dialog.py · sessions.py
    settings.py · settings_dialog.py · main_window.py · app.py · theme.py

License

MIT

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.

turbossh-0.18.7-py3-none-any.whl (80.4 MB view details)

Uploaded Python 3

File details

Details for the file turbossh-0.18.7-py3-none-any.whl.

File metadata

  • Download URL: turbossh-0.18.7-py3-none-any.whl
  • Upload date:
  • Size: 80.4 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for turbossh-0.18.7-py3-none-any.whl
Algorithm Hash digest
SHA256 513725250bd3ca7bb00e1035b467fa900afc3e2b766015b902a2d1589f57e4aa
MD5 f4cf18c22b2b24cf743803df217a64fd
BLAKE2b-256 2347e938b7b186100425e6de29315886b4f12eb293ef67716487c554c25821e9

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