ftptui

Interaktiver FTP- und SFTP-Client als Terminal-User-Interface in Python.

ftptui ist ein schlanker, aber vollwertiger Dateibrowser für die Kommandozeile. Er unterstützt klassisches FTP (RFC 959, über die Python-Standardbibliothek ftplib) sowie SFTP (SSH File Transfer Protocol, über paramiko). Damit deckt das Tool den überwiegenden Teil der realen Dateiübertragungs-Szenarien ab – einschließlich SSH-basiertem FTP.

Das Interface ist zweispaltig aufgebaut:

  • links das lokale Dateisystem,
  • rechts das entfernte System,

mit Dateiübertragung in beide Richtungen, rekursivem Hoch-/Herunterladen von Verzeichnissen, Anlegen, Umbenennen und Löschen sowie speicherbaren Verbindungsprofilen.


Inhaltsverzeichnis


Funktionen

  • Dual-Pane-Dateibrowser – lokales und entferntes Verzeichnis nebeneinander, Spalten: Name, Größe, Änderungsdatum.
  • FTP über die Standardbibliothek, SFTP über paramiko (SSH-FTP).
  • Herunterladen (l) und Hochladen (u) einzelner Dateien.
  • Rekursive Übertragung kompletter Verzeichnisbäume.
  • Verzeichnisse anlegen (n), umbenennen (r), löschen (d), rekursives Löschen nicht-leerer Ordner.
  • Navigation mit Maus/Tastatur, „eine Ebene hoch“ (←), Doppelklick/Enter.
  • Verbindungsprofile werden als JSON unter ~/.config/ftptui/profiles.json gespeichert und können wieder geladen werden.
  • Passwortfelder sind abgedunkelt (password=True).
  • Modernes, terminalfreundliches Layout auf Basis von Textual.

Unterstützte Protokolle

Protokoll Beschreibung Bibliothek / Quelle
ftp Klassisches File Transfer Protocol (RFC 959) Standard (kein Drittpaket nötig)
sftp SSH File Transfer Protocol (SSH-FTP) paramiko

Hinweis: „SSH-FTP“ kann zweierlei bedeuten – das SFTP-Subsystem über eine SSH-Schicht (hier umgesetzt) oder FTP über einen SSH-Tunnel (sog. „FTP over SSH“). In ftptui wird SFTP über SSH unterstützt, der heute übliche und sichere Weg.


Installation

Voraussetzungen

  • Python ≥ 3.10
  • pip und idealerweise eine virtuelle Umgebung

Aus dem Quellverzeichnis

# virtuelle Umgebung anlegen und aktivieren
python3 -m venv .venv
source .venv/bin/activate

# Abhängigkeiten installieren
pip install -e .

# Abhängigkeiten (nur Laufzeit):
#   textual  - TUI-Framework
#   paramiko - SFTP/SSH

Als Paket

pip install .

Als installiertes Kommando

Nach pip install -e . steht das Kommando ftptui global in der Umgebung bereit:

ftptui

Verwendung

  1. Starten: ftptui

  2. Im Verbindungsbildschirm die Daten eingeben:

    • Verbindungsprofil – ein zuvor gespeichertes Profil auswählen, oder ein neues anlegen.
    • Protokoll – sftp (SSH) oder ftp.
    • Host, Port (SFTP-Vorgabe 22, FTP-Vorgabe 21), Benutzer, Passwort.
    • Auf Verbinden klicken. Der Port wird bei Protokollwechsel automatisch auf den jeweiligen Standard gesetzt.
  3. Nach erfolgreicher Verbindung erscheint der Browser-Bildschirm mit zwei Panelen:

    • links / des lokalen Rechners bzw. das Home-Verzeichnis,
    • rechts das Home-/Root-Verzeichnis des entfernten Systems.
  4. Zwischen den Paneelen wechseln mit Tab. Die fokussierte Tabelle erhält die Aktionen (Hoch-/Herunterladen, Umbenennen, Löschen …).

Tipp: Die Aktionen u/l wirken auf das gerade in der fokussierten Tabelle angewählte Element und übertragen in die jeweils andere Seite.


Tastaturkürzel

Taste Aktion
Tab Zwischen lokalem/entferntem Paneel wechseln
Enter Ordner öffnen / in Datei wechseln
← Eine Verzeichnisebene höher
↑ .. Eine Ebene hoch (Tabellenzeile)
l Auswahl herunterladen (entfernt → lokal)
u Auswahl hochladen (lokal → entfernt)
n Neues Verzeichnis anlegen
d Auswahl löschen (rekursiv)
r Auswahl umbenennen
q / Esc Beenden

Projektstruktur

ftptui/
├── pyproject.toml          # Paketmetadaten, Abhängigkeiten, Einstiegspunkt
├── README.md               # diese Dokumentation
├── .gitignore
└── ftptui/
    ├── __init__.py         # Versionsnummer
    ├── app.py              # Textual-TUI: Verbindungs- & Browser-Bildschirme
    ├── backend.py          # Fabrik: wählt FTP- oder SFTP-Transport
    ├── config.py           # Speicherung/Laden der Verbindungsprofile (JSON)
    ├── models.py           # Datentypen & Transport-Protokoll
    ├── ftp_backend.py      # FTP-Adapter (ftplib)
    └── sftp_backend.py     # SFTP-Adapter (paramiko)

Architektur

Die App trennt Oberfläche (Textual) von Transport (Netzwerkprotokolle) durch ein kleines Protokoll/Interface:

  • FileTransferBackend (in models.py) definiert die gemeinsame API.
  • FTPBackend und SFTPBackend implementieren sie.
  • create_backend(protocol) in backend.py liefert den passenden Adapter.

Gemeinsame Schnittstelle (Auszug):

def connect(host, port, username, password) -> None
def listdir(path)            -> list[RemoteEntry]
def chdir(path) / pwd()      -> str
def download(remote, local)  -> None
def upload(local, remote)    -> None
def mkdir(path) / remove / rmdir / rename
def close()                  -> None

RemoteEntry beschreibt einen Eintrag mit name, kind (file/dir), size und modified. Dadurch kann die Oberfläche unabhängig vom Protokoll arbeiten – das Hinzufügen weiterer Backends (z. B. WebDAV) ist ohne Änderung der UI möglich.

Pfadbehandlung

Beide Backends normalisieren Pfade zu absoluten Angaben relativ zum Root des entfernten Systems. FTP-Operationen setzen das Arbeitsverzeichnis vor einer Aktion auf /, sodass Dateiübertragungen unabhängig vom zuletzt betrachteten Ordner zuverlässig funktionieren. SFTP nutzt absolute Pfade direkt.

Profilwertung

Profile werden als JSON in ~/.config/ftptui/profiles.json (bzw. $XDG_CONFIG_HOME/ftptui/profiles.json) gespeichert. Das Passwort wird nur abgelegt, wenn es entsprechend markiert wurde (aktuell standardmäßig direkt gespeichert – Datenschutz-Hinweis siehe unten).


Konfiguration & Profile

Profile speichern: im Verbindungsbildschirm Daten eingeben und Profil speichern drücken. Gespeicherte Einträge erscheinen künftig im Dropdown Verbindungsprofil.

Beispieldatei ~/.config/ftptui/profiles.json:

[
  {
    "name": "git.sysdaemon.xyz",
    "protocol": "sftp",
    "host": "git.sysdaemon.xyz",
    "port": 22,
    "username": "user",
    "password": "",
    "save_password": false
  },
  {
    "name": "backup-server",
    "protocol": "ftp",
    "host": "backup.local",
    "port": 21,
    "username": "ftpuser",
    "password": "secret",
    "save_password": true
  }
]

Sicherheitshinweis: Speichern Sie Passwörter in Profilen nur auf vertrauenswürdigen Systemen. Die Datei liegt im Klartext im Benutzerverzeichnis.


Entwicklung

# Umgebung
python3 -m venv .venv && source .venv/bin/activate
pip install -e . "textual>=0.80.0" "paramiko>=3.4.0"

# Laufzeit prüfen
python -c "import ftptui; print(ftptui.__version__)"

# App booten (Konsolen-Test)
ftptui

Code-Stil & Qualität

  • Typannotationen (from __future__ import annotations) durchgängig.
  • Protokoll-/Interface-basierte Implementierung mit typing.Protocol.
  • Keine Abhängigkeit auf Drittanbieter außer textual und paramiko.

Testen

Die Backends werden gegen lokale Testserver end-to-end getestet:

  • FTP gegen pyftpdlib (nur für Tests; nicht Teil der Laufzeit-Abhängigkeiten),
  • SFTP gegen eine eigene paramiko-SSH-Server-Implementierung.

Ablauf der Tests: Verbinden, Listings, Download, Upload, mkdir, rename, remove, rekursives rmdir, close – für beide Protokolle.

pip install pyftpdlib
python tests/test_backends.py   # Beispieldatei (siehe Entwicklung/Skripte)

Ein ausführbares Testskript kann ergänzt und an dieser Stelle dokumentiert werden; die Backends sind derart modular, dass sie ohne Terminal getestet werden können.


Lizenz

MIT – siehe Projektträger/Repositories. Keine gewerblichen Einschränkungen.


Projekt wird innerhalb der sysdaemon.xyz-Instanz über Gitea verwaltet – https://git.sysdaemon.xyz/admin/ftptui.

S
Description
FTP/SFTP TUI-Client in Python mit SSH-FTP-Unterstützung
Readme
116 KiB
Languages
Python 91.9%
Shell 8.1%