Ich habe in einem Projekt ein wenig mit Python 3.x gearbeitet und habe beim Hochladen per FTP eine Fehlermeldung erhalten die nicht direkt schlüssig/selberklärend war.

521 Data connection cannot be opened with this PROT setting.

Als erstes den Code bei dem das Problem auftritt (habe ich auch bei stackoverflow.com gefunden):

import os
import ftplib
 
ftp = ftplib.FTP_TLS('ftp.server', 'username', 'password')
 
ftpFolder = '/'
 
ftp.cwd(ftpFolder)
 
absolutepath = os.path.abspath(".")
 
for root, dirs, files in os.walk(absolutepath, topdown = True):
    relative = root[len(absolutepath):].lstrip(os.sep)
 
    for d in dirs:
        ftp.mkd(os.path.join(relative, d))
 
    for f in files:
        ftp.cwd(relative)
        ftp.storbinary('STOR ' + f, open(os.path.join(absolutepath, relative, f), 'rb'))
        ftp.cwd("/")
 
ftp.close()

Bei der Zeile „ftp.storbinary(..)“ erhalte ich die nachfolgende Meldung:

521 Data connection cannot be opened with this PROT setting.

Nach dem Lesen der Dokumentation von ftplib und einigen Experimenten habe ich die Lösung gefunden. Nach dem Login (in meinem Beispiel-Code wird das automatisch beim Aufruf des Konstruktors gemacht), muss noch „prot_p()“ aufgerufen werden, dass ist aber nur notwendig wenn man FTP mit SSL/TLS benutzt. Jetzt nochmal den kompletten Code, der funktioniert:

import os
import ftplib
 
ftp = ftplib.FTP_TLS('ftp.server', 'username', 'password')
ftp.prot_p()  # Diese Zeile ist entscheidend!
 
ftpFolder = '/'
 
ftp.cwd(ftpFolder)
 
absolutepath = os.path.abspath(".")
 
for root, dirs, files in os.walk(absolutepath, topdown = True):
    relative = root[len(absolutepath):].lstrip(os.sep)
 
    for d in dirs:
        ftp.mkd(os.path.join(relative, d))
 
    for f in files:
        ftp.cwd(relative)
        ftp.storbinary('STOR ' + f, open(os.path.join(absolutepath, relative, f), 'rb'))
        ftp.cwd("/")
 
ftp.close()