python
import logging
import os
from pathlib import Path
import paramiko
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
log = logging.getLogger(__name__)
REMOTE = 'upload'
ARCHIV = f'{REMOTE}/archiv'
LOKAL = Path('eingang')
def verbinde():
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.RejectPolicy())
ssh.connect(
hostname=os.environ['SFTP_HOST'],
port=int(os.environ.get('SFTP_PORT', '22')),
username=os.environ['SFTP_USER'],
password=os.environ['SFTP_PASSWORD'],
timeout=15,
)
return ssh
def stelle_ordner_sicher(sftp, pfad):
try:
sftp.stat(pfad)
except FileNotFoundError:
sftp.mkdir(pfad)
def main():
LOKAL.mkdir(exist_ok=True)
with verbinde() as ssh, ssh.open_sftp() as sftp:
stelle_ordner_sicher(sftp, ARCHIV)
for name in sftp.listdir(REMOTE):
if not name.lower().endswith('.csv'):
continue
ziel = LOKAL / name
if ziel.exists():
log.warning('%s existiert lokal schon, übersprungen', name)
continue
sftp.get(f'{REMOTE}/{name}', str(ziel))
sftp.rename(f'{REMOTE}/{name}', f'{ARCHIV}/{name}')
log.info('%s geholt und archiviert', name)
if __name__ == '__main__':
main()
Was passiert:
sftp.listdir(REMOTE)liefert alle Namen im Ordner, aucharchiv. Dankendswith('.csv')wird der Ordner übersprungen, ebenso andere Dateitypen.lower()fängt.CSVab.stelle_ordner_sicherfragt perstat, ob der Ordner da ist. Fehlt er, löststateinenFileNotFoundErroraus, der abgefangen wird, und der Ordner wird angelegt. Dieses Muster "erst versuchen, bei Fehler anlegen" ist in Python üblich.- Erst nach erfolgreichem
getwird verschoben. Schlägt der Download fehl, bleibt die Datei auf dem Server liegen und wird beim nächsten Lauf erneut versucht. - Die Log-Meldungen nutzen
%s-Platzhalter statt f-Strings. Das ist die empfohlene Schreibweise fürlogging, denn der Text wird nur zusammengebaut, wenn die Meldung tatsächlich ausgegeben wird.
Warum so: Ein Skript, das Dateien holt und archiviert, kann ohne Sorge wiederholt laufen (zum Beispiel per Cron oder als geplanter Container), weil schon verarbeitete Dateien nicht erneut geholt werden. Das macht Automatisierung robust.