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.
  • Menu bar (File / Edit / View / Session / Help) with icons — New session, Save output, Set up SSH server, Copy/Paste/Clear, Split, Check for updates…
  • True VT100 terminal (pyte) — full-screen apps (htop, vim, top, less, nano) render correctly, with colors, a block cursor, and live PTY resize.
  • 5000-line scrollback — wheel up to read old output; typing snaps back to the live tail. Save all output writes the entire session, not just what's on screen.
  • 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 — local, or on a remote RDP machine over SSH with a one-click Scan remote to list that machine's COM ports.
  • 🖧 SSH server button — turn this Windows box into an SSH server, offline, from the bundled OpenSSH (see below).
  • Check for updates — one click pulls the latest from PyPI and reinstalls.
  • Settings — dark/light theme, terminal font + size, default baud (persisted, applied live).
  • 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)

Run this on the RDP / Windows machine to turn it into an SSH server — so TurboSSH (and your scripts) can reach it, including the COM ports plugged into it. It's fully offline: the OpenSSH binaries (ARM64 / Win64 / Win32) ship inside the package, so it works on locked-down corporate networks where downloads are blocked.

From the GUI (easiest): click 🖧 SSH server in the ribbon. Choose:

  • This PC — approve the Administrator prompt; it installs OpenSSH Server, starts sshd, opens the firewall, fixes host keys, and the GUI confirms when it's listening.
  • A remote machine (WinRM) — install OpenSSH on another Windows box from here, fully offline: the bundled OpenSSH is pushed over WinRM and installed remotely. Needs WinRM (port 5985) reachable and a local-admin account on the target — handy for enabling SSH on an RDP machine without logging into it.

From the terminal:

turbossh-setup            # self-elevates, installs OpenSSH Server from the bundled
                          # ZIP (ARM64/Win64/Win32), starts sshd, opens firewall,
                          # generates + fixes host keys. No internet / Windows Update.
turbossh-setup --InstallPip --Port 22   # also pip-install turbossh; custom port

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

Tip: this is the "serve" step — do it once per RDP machine and you'll never have to remember to enable SSH by hand again.

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.19.6-py3-none-any.whl (90.4 MB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: turbossh-0.19.6-py3-none-any.whl
  • Upload date:
  • Size: 90.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.19.6-py3-none-any.whl
Algorithm Hash digest
SHA256 fb94646ca24787608212cddd093fa2bce170a23938da2fef91bbb0add43ac00f
MD5 de4625740d2fadf92dab12306ef60ab5
BLAKE2b-256 502bfc53dab7f292718a97711fd513b803bb325b3efa56b938b0fc7919061fe3

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