Need to connect to ftp through the ftputil module, open an existing file with records and add new records to the end of those records

568 Views Asked by At

I used the ftputil module for this, but ran into a problem that it doesn't support 'a'(append) appending to the file, and if you write via 'w' it overwrites the contents.

That's what I tried and I'm stuck there:

with ftputil.FTPHost(host, ftp_user, ftp_pass) as ftp_host:
      with ftp_host.open("my_path_to_file_on_the_server", "a") as fobj:
         cupone_wr = input('Enter coupons with a space: ')
         cupone_wr = cupone_wr.split(' ')
         for x in range(0, len(cupone_wr)):
             cupone_str = '<p>Your coupon %s</p>\n' % cupone_wr[x]
             data = fobj.write(cupone_str)
         print(data)

The goal is to leave the old entries in the file and add fresh entries to the end of the file every time the script is called again.

2

There are 2 best solutions below

0
Martin Prikryl On BEST ANSWER

Indeed, ftputil does not support appending. So either you will have to download complete file and reupload it with appended records. Or you will have to use another FTP library.

For example the built-in Python ftplib supports appending. On the other hand, it does not (at least not easily) support streaming. Instead, it's easier to construct the new records in-memory and upload/append them at once:

from ftplib import FTP
from io import BytesIO

flo = BytesIO() 

cupone_wr = input('Enter coupons with a space: ')
cupone_wr = cupone_wr.split(' ')
for x in range(0, len(cupone_wr)):
    cupone_str = '<p>Your coupon %s</p>\n' % cupone_wr[x]
    flo.write(cupone_str)

ftp = FTP('ftp.example.com', 'username', 'password')

flo.seek(0)
ftp.storbinary('APPE my_path_to_file_on_the_server', flo)
2
sschwarzer On

ftputil author here :-)

Martin is correct in that there's no explicit append mode. That said, you can open file-like objects with a rest argument. In your case, rest would need to be the original length of the file you want to append to.

The documentation warns against using a rest argument that points after the file because I'm quite sure rest isn't expected to be used that way. However, if you use your program only against a specific server and can verify its behavior, it might be worthwhile to experiment with rest. I'd be interested whether it works for you.