Python FTP server timeout control
I'm having a problem with socket timeouts with python35 ftplib. When a socket timeout error occurs, for some reason I cannot catch the exception and the script still throws the error and exits. Here's the relevant code block:
try:
ftp = FTP(self.config.base_url, timeout=400)
ftp.login()
ftp.cwd(self.config.root_path)
ftp.retrbinary("RETR {0}".format(os.path.join(self.root_path, file_path)), fp.write, 1024)
ftp.quit()
except socket.timeout:
self.download_file(file_path)
For some reason this script will still crash with a socket timeout exception, how is this possible? Common gimmicks don't work either. Here is the stack trace of the error:
File "ftp.py", line 82, in __init__ self.ftp = FTP(self.config.base_url, timeout=400) File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ftplib.py", line 118, in __init__ self.connect(host) File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ftplib.py", line 156, in connect self.welcome = self.getresp() File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ftplib.py", line 235, in getresp resp = self.getmultiline() File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ftplib.py", line 221, in getmultiline line = self.getline() File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ftplib.py", line 203, in getline line = self.file.readline(self.maxline + 1) File "/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/socket.py", line 576, in readinto return self._sock.recv_into(b) socket.timeout: timed out
As you can see it is socket.timeout error since it is not caught? I was unable to find any useful information on how to solve this problem after many hours of internet research, any understanding of this problem would be greatly appreciated.
For reference, here is the corresponding socket.py code block:
def readinto(self, b):
"""Read up to len(b) bytes into the writable buffer *b* and return
the number of bytes read. If the socket is non-blocking and no bytes
are available, None is returned.
If *b* is non-empty, a 0 return value indicates that the connection
was shutdown at the other end.
"""
self._checkClosed()
self._checkReadable()
if self._timeout_occurred:
raise OSError("cannot read from timed out object")
while True:
try:
return self._sock.recv_into(b)
except timeout:
self._timeout_occurred = True
raise
except error as e:
if e.args[0] in _blocking_errnos:
return None
raise
UPDATE: It looks like the problem is that ftplib behaves unexpectedly if the timeout passed to the FTP constructor is greater than the default socket timeout. At the time of this edit, there is an open python issue to resolve this behavior: http://bugs.python.org/issue30956
source to share
No one has answered this question yet
Check out similar questions: