Reputation: 11
This one is not making any sense to me. Apologies for my poor python, I'm relatively new to the language.
The pertinent part of my program looks like:
from ftplib import FTP, FTP_TLS
...
try:
ftps = FTP(server, user = user, passwd = password,
encoding='ISO8859-1'
)
# ftps.prot_p()
login = True
except:
print("Login failed, retry")
...
for member in members:
ftps.retrlines(f'RETR {member}', lines.append)
fp = open(f'{dest}/{type}/{member}{sep}{suffix}', 'w',
encoding='ISO8859-1', errors='backslashreplace')
line_number = 0
for line in lines:
line_number += 1
bad = [line_number, line]
line = line.replace('\xdd', '|')
try:
fp.write(line.rstrip() + '\n')
except:
print(f"line {bad[0]} in {type} member:",
f"{member}{sep}{suffix} - {bad[1]}")
fp.close()
...
This works fine and has been for a couple of years. However, when I change it to:
ftps = FTP_TLS(server, user = user, passwd = password,
encoding='ISO8859-1'
)
ftps.prot_p()
login = True
I get: File "~\Local\Programs\Python\Python311\Lib\ftplib.py", line 218, in getline raise EOFError EOFError
I tried wrapping the ftps.retrlines() in a try/except clause to ignore the EOFError (a suggestion from another SO thread) but that caused even more ssl errors.
I've looked at the files on the server and after they were downloaded (at least it is consistent where the error occurs) and don't see anything in the source file to cause this. Looking at the (server) file immediately prior to and following the file "in error", both look fine and download without issues if I don't use FTP_TLS.
Full disclosure, the server is a z/OS server with FTPS enabled and these are members of PDSs on z/OS.
TIA
Upvotes: 1
Views: 157
Reputation: 11
Update: I got this working with:
while member := Paths.current_member().lower():
sourcefile = f'{Paths.current_source}({member})'
if myType in exceptions and member in exceptions[myType]:
logit(f'Skipping {sourcefile}')
Paths.next_member()
continue
logit(f'Retrieving {sourcefile}')
lines.clear()
try:
myFTP.connection.retrlines(f'RETR {member}', lines.append)
except:
print(f'Error retrieving {sourcefile}, retrying')
myFTP.re_connect() #log back in
myFTP.connection.cwd(f"'{Paths.current_source}'")
continue #try again
suffix = suffixes.get(myType, '')
sep = '.' if suffix else ''
destfile = f'{Paths.current_dest}/{member}{sep}{suffix}'
logit(f'Saving to {destfile}')
fp = open(destfile, 'w',
encoding='ISO8859-1', errors='backslashreplace')
line_number = 0
for line in lines:
line_number += 1
bad = [line_number, line]
line = line.replace('\xdd', '|')
try:
fp.write(line.rstrip() + '\n')
except:
print(f"line {bad[0]} in {myType} member:",
f"{member}{sep}{suffix} - {bad[1]}")
fp.close()
Paths.next_member()
myFTP is a class I created to store FTP related information and Paths stores source and destination paths. I could have used a bunch of global variables but thought the classes were a bit more pythonic.
Apparently the server has some limit on the amount of data that can be transferred via FTPS and cuts it off after a while. Adding the re-connect/retry logic solved the issue.
Maybe this will help someone else trying to implement mass transfers with via FTPS.
Upvotes: 0