Erstellen Sie SFTP-Funktionalität in Python

Olorunfemi Akinlua 16 Februar 2024
  1. Verwenden Sie pysftp, um SFTP-Funktionalität in Python zu erstellen
  2. Verwenden Sie paramiko, um SFTP-Funktionalität in Python zu erstellen
Erstellen Sie SFTP-Funktionalität in Python

Secure Socket Shell (SSH) ist ein sicheres und besseres Netzwerkprotokoll, das uns den Zugriff auf einen anderen Computer ermöglicht und ein Passwort und die Authentifizierung mit öffentlichem Schlüssel über SHA und Verschlüsselung verwendet.

SSH File Transfer Protocol (SFTP) ist ein Dateiübertragungsprotokoll, das SSH verwendet und besser ist als das typische FTP, das früher verwendet wurde.

Für die Entwicklung unserer Anwendung in Python ist möglicherweise ein Dateiübertragungsprotokoll erforderlich. Wir sollten das SFTP verwenden, das uns standardmäßig die Möglichkeit gibt, Angriffe wie Passwort-Sniffing und Man-in-the-Middle zu überwinden und unsere Datenintegrität zu wahren.

Dieser Artikel zeigt Ihnen, wie Sie SFTP in Ihrem Python verwenden, um Ihre Daten und Dateien zu verschieben.

Verwenden Sie pysftp, um SFTP-Funktionalität in Python zu erstellen

Python enthält ftplib, eine FTP-Client-Klasse mit Hilfsfunktionen, die den unsicheren FTP-Protokolldienst bereitstellen. Damit wir SFTP verwenden können, müssen wir Bibliotheken von Drittanbietern installieren, und eine dieser Bibliotheken ist die pysftp-Bibliothek.

Mit pysftp können Sie auf SFTP zugreifen und mit dem sicheren Protokoll arbeiten, um Ihre Anwendungsanforderungen zu erfüllen. Um pysftp zu installieren, müssen Sie pip verwenden.

pip install pysftp

Außerdem benötigen wir einen SFTP-Server. Für Windows verwenden wir die Software WinSCP, und um zu erfahren, wie Sie einen SFTP-Server-Client auf Ihrem Windows-PC einrichten, können Sie diese Installationsanleitung durchgehen. Wenn Sie jedoch einen SFTP-Server haben, fangen wir an.

Bevor wir Code schreiben, melden wir uns mit unserem privaten Schlüssel, dem Benutzernamen (akinl) und dem Hostnamen (localhost) bei unserem SFTP-Server an.

SFTP-Funktionalität in Python erstellen - Erweiterte Site-Einstellungen

Jetzt sind wir im Ordner root angemeldet. Unser Ziel wird es sein, die Dateien und Verzeichnisse aufzulisten, die im root-Verzeichnis vorhanden sind, und Dateien auf den SFTP-Server zu kopieren, insbesondere das store-Verzeichnis.

SFTP-Funktionalität in Python erstellen - beim SFTP-Server angemeldet

Beginnen wir mit dem Codieren mit der vordefinierten Codevorlage, die von der Bibliothek pysftp angegeben wird. Innerhalb des Codes haben wir unseren Hostnamen, port, Benutzernamen und Pfad des privaten Schlüssels zugewiesen.

Diese Werte werden von Ihren SFTP-Serverdetails mitgeteilt, und der private key wird in das Verzeichnis der Python-Datei kopiert.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    print("Connected to SFTP server!")

Der obige Code stellt über ein SFTP-Verbindungsobjekt (pysftp.Connection()) mit den angegebenen Parametern eine Verbindung zum SFTP-Server her. Innerhalb des with-Blocks haben wir eine etablierte SFTP-Verbindung innerhalb des Objekts namens sftp.

Es folgt eine Ausgabe des Codes:

C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py:61: UserWarning: Failed to load HostKeys from C:\\Users\\akinl\\.ssh\\known_hosts. You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None).
  warnings.warn(wmsg, UserWarning)
Traceback (most recent call last):
  File "c:\\Users\\akinl\\Documents\\Python\\SFTP\\index.py", line 8, in <module>
    with pysftp.Connection(host=sftpHostName, port=sftpPort, username=userName, private_key=privateKeyPath) as sftp:
  File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 132, in __init__
    self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
  File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 71, in get_hostkey
    raise SSHException("No hostkey for host %s found." % host)
paramiko.ssh_exception.SSHException: No hostkey for host localhost found.
Exception ignored in: <function Connection.__del__ at 0x000001F0E9656320>
Traceback (most recent call last):
  File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 1013, in __del__
    self.close()
  File "C:\\Python310\\lib\\site-packages\\pysftp\\__init__.py", line 784, in close
    if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live'

Kein Hostschlüssel für Host %s gefunden ist ein häufiger Fehler beim Arbeiten mit SFTP-Verbindungsobjekten mit pysftp, der auftritt, wenn die Hostdatei nicht vorhanden ist.

Um das Problem zu lösen, können wir Verbindungsoptionen erstellen (pysftp.CnOpts()), angeben, dass die Hostschlüssel None sind, und die Prüfung auf bekannte Hosts ignorieren.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    print("SFTP server connection successful")

Die Ausgabe des Codes ist wie folgt:

C:\Python310\lib\site-packages\pysftp\__init__.py:61: UserWarning: Failed to load HostKeys from C:\Users\akinl\.ssh\known_hosts. You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None).
  warnings.warn(wmsg, UserWarning)
SFTP server connection successful

Der einzige Fehler, den wir haben, ist eine Low-Level-Warnung über die deaktivierte Überprüfung des Hostschlüssels. Lassen Sie uns zunächst das Arbeitsverzeichnis ändern, um Ihnen anzuzeigen, dass wir uns auf dem SFTP-Server befinden.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    print("SFTP server connection successful")
    print("The current working directory is ", sftp.pwd)
    sftp.cwd("./store")
    print("After the cwd operation, the current working directory is ", sftp.pwd)

Die Ausgabe des obigen Codes ist unten angegeben:

SFTP server connection successful
The current working directory is /
After the cwd operation, the current working directory is /store.

Das cwd ändert das aktuelle Arbeitsverzeichnis in das, was als Argument angegeben ist. Außerdem können wir die Dateien in den Verzeichnissen root und store mit der Methode listdir() auflisten und die Dateien in der

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    rootFiles = sftp.listdir()
    storeFiles = sftp.listdir("./store")
    print(rootFiles, storeFiles)

Die Ausgabe des Codes ist wie folgt:

['index.txt', 'main.py', 'store'] []

Die Methode listdir() listet alle Dateien und Verzeichnisse innerhalb des aktuellen Arbeitsverzeichnisses auf, wenn kein Argument übergeben wird, aber wenn wir ein Argument angeben, sucht sie nach Dateien innerhalb des übergebenen Arguments. Das Ergebnis waren zwei Dateien und ein Verzeichnis für das Verzeichnis root und keine für das Verzeichnis store, da keine Datei existiert.

Lassen Sie uns nun einige Dateien mit einigen Methoden, put(), put_d() und put_r(), auf unseren SFTP-Server verschieben. Wir verwenden put(), um nur Dateien zu verschieben.

Erstellen Sie als nächstes eine Textdatei namens test.txt im selben Verzeichnis wie unsere Python-Datei und kopieren Sie die Datei auf den SFTP-Server.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    sftp.put("test.txt", preserve_mtime=True)

Die Ausgabe des Codes:

sftp-Funktionalität in Python erstellen - Ausgabe

Die Datei test.txt befindet sich nun im Stammverzeichnis des SFTP-Servers. Lassen Sie uns nun dieselbe test.txt in das store-Verzeichnis verschieben und ihren Dateiinhalt vor und nach dem Kopieren auflisten.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    print(sftp.listdir("./store"))
    sftp.put("test.txt", preserve_mtime=True, remotepath="./store/upload.txt")
    print(sftp.listdir("./store"))

Die Ausgabe des obigen Codes zeigt, dass die Datei test.txt als upload.txt auf den Server hochgeladen wurde und im Bild sichtbar ist.

[]
['upload.txt']

SFTP-Funktionalität in Python erstellen - Ausgabe hochladen

Wir können den Inhalt eines Verzeichnisses mit der Methode put_d() kopieren. Erstellen wir zum Beispiel ein Verzeichnis SeptData mit drei Textdateien (one.txt, two.txt und three.txt) und kopieren den Inhalt des Verzeichnisses in den Ordner root.

Für den Pfad, aus dem kopiert werden soll, benötigen wir jedoch den vollständigen Pfad, nicht den relativen Pfad, den wir zuvor verwendet haben.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    print(sftp.listdir("./"))
    sftp.put_d(
        r"C:\Users\akinl\Documents\Python\SFTP\SeptData", "./", preserve_mtime=True
    )
    print(sftp.listdir("./"))

Die Ausgabe des Codes:

['index.txt', 'main.py', 'store', 'test.txt']
['index.txt', 'main.py', 'one.txt', 'store', 'test.txt', 'three.txt', 'two.txt']

Die drei Dateien befinden sich nun im root-Verzeichnis, dargestellt durch die Liste der Dateien und Verzeichnisse innerhalb des Verzeichnisses. Daher können wir mit der Methode get() Dateien vom SFTP-Server herunterladen.

import pysftp

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

cnOptions = pysftp.CnOpts()
cnOptions.hostkeys = None

with pysftp.Connection(
    host=sftpHostName,
    port=sftpPort,
    username=userName,
    private_key=privateKeyPath,
    cnopts=cnOptions,
) as sftp:
    sftp.get("./store/upload.txt", preserve_mtime=True)

Nach erfolgreicher Ausführung des Codes ist die Datei upload.txt im Verzeichnis der Python-Datei vorhanden. Sie können entfernte Verzeichnisse mit den Methoden get_d() und get_r() abrufen.

Verwenden Sie paramiko, um SFTP-Funktionalität in Python zu erstellen

Paramiko ist eine großartige Bibliothek, die über ihre Klassen und Methoden eine unkomplizierte Implementierung von SSHv2 für Python bereitstellt. Wir können einige dieser Methoden verwenden, um Verbindungen zu einem SFTP-Server zu initiieren und mit diesem Server über die public key-Authentifizierung zu arbeiten.

Um paramiko zu installieren, können Sie den Befehl pip wie folgt verwenden:

pip install paramiko

Mit den Verbindungsdetails aus dem letzten Abschnitt können wir die gleichen Vorgänge ausführen, vom Wechseln der Arbeitsverzeichnisse bis zum Abrufen von Dateien vom Remote-SFTP-Server.

Das SSHClient() erstellt ein neues SSH für uns, um uns mit dem SFTP-Server zu verbinden, und das set_missing_host_key_policy() ermöglicht es uns, eine Richtlinie für die Verbindung zu Servern ohne bekannten Hostschlüssel und die connect()-Methode festzulegen stellt die eigentliche Verbindung zum SFTP-Server her.

Lassen Sie uns das Verzeichnis in das Verzeichnis store ändern und das aktuelle Arbeitsverzeichnis und den Inhalt des besagten Verzeichnisses mit Hilfe von chdir, getcwd bzw. listdir drucken.

import paramiko

sftpHostName = "localhost"
sftpPort = 22
userName = "akinl"
privateKeyPath = "./id_rsa"

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(
    hostname=sftpHostName, port=sftpPort, username=userName, key_filename=privateKeyPath
)

sftp_client = ssh.open_sftp()
sftp_client.chdir("./store")
print(sftp_client.getcwd())
print(sftp_client.listdir())

sftp_client.close()
ssh.close()

Die Ausgabe des Codes:

/store
['one.txt', 'three.txt', 'two.txt', 'upload.txt']

Die erste Zeile enthält das aktuelle Arbeitsverzeichnis, das durch die Methode chdir() gesetzt wurde, und die zweite Zeile enthält eine Liste der Dateien und Verzeichnisse innerhalb des Verzeichnisses store.

Olorunfemi Akinlua avatar Olorunfemi Akinlua avatar

Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.

LinkedIn