I am trying to connect to connect to a FTP site to download some files:
from ftplib import FTP_TLS
from ftplib import FTP
import ssl
import ftplib
FTP_TLS.ssl_version = ssl.PROTOCOL_TLSv1_2
ftps = FTP_TLS(timeout=100)
ftps.set_debuglevel(2)
ftps.connect('IP', port)
ftps.auth()
ftps.prot_p()
ftps.login('username', 'password')
The program tries for sometime before it fails with the following error:
get '' Traceback (most recent call last): File "FTP.py", line 12, in ftps.connect('IP', port) File "C:_data\learn\Miniconda\lib\ftplib.py", line 155, in connect self.welcome = self.getresp() File "C:_data\learn\Miniconda\lib\ftplib.py", line 236, in getresp resp = self.getmultiline() File "C:_data\learn\Miniconda\lib\ftplib.py", line 222, in getmultiline line = self.getline() File "C:_data\learn\Miniconda\lib\ftplib.py", line 210, in getline raise EOFError EOFError
I am not sure what the cause of this error is . I can connect to the ftp server using the same details with a FTP client (FileZilla). Can anyone point out if there is issue with my code and possible options to fix this.
Edit 1
As suggested below posting FileZilla logs :
Status: Connecting to IP:Port... Status: Connection established, initializing TLS... Status: Verifying certificate... Status: TLS connection established, waiting for welcome message... Status: Logged in Status: Retrieving directory listing... Status: Directory listing of "/" successful
FIleZilla explicitly pops up a certificate which I press OK on my desktop after which the connection is established. I am assuming the failure here is because my code doesn't accept the certificate. Any help is appreciated.
For anyone looking for an answer, the issue was that implicit FTPS connections need the socket to be ssl wrapped automatically.I used the below piece of code written by George Leslie-Waksman
import ftplib
import ssl
class ImplicitFTP_TLS(ftplib.FTP_TLS):
"""FTP_TLS subclass that automatically wraps sockets in SSL to support implicit FTPS."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._sock = None
@property
def sock(self):
"""Return the socket."""
return self._sock
@sock.setter
def sock(self, value):
"""When modifying the socket, ensure that it is ssl wrapped."""
if value is not None and not isinstance(value, ssl.SSLSocket):
value = self.context.wrap_socket(value)
self._sock = value
If this resolves your issue, kindly upvote the original answer -->https://stackoverflow.com/a/36049814/392233