'Create a ZipFile in memory and attach it to an email

I'm trying to modify an existing python script to convert an in-memory CSV into an (also in memory) zip archive and send it as an attachment to an email. I've had success attaching an in memory CSV file (via a MIMEText object) but am having trouble with the ZIP file (via a MIMEBase object) due to the requirements to setting the payload of the file's bytes.

This is the code I have so far:

csv_buffer = cStringIO.StringIO()
buffer = cStringIO.StringIO()

zf = zipfile.ZipFile(buffer,
               mode='w',
               compression=zipfile.ZIP_DEFLATED,
               )

zf.writestr(csvfile + ".csv", csv_buffer.getvalue())


csv_file = MIMEBase('application', 'zip')
csv_file.set_payload(zf.read())
encoders.encode_base64(csv_file)
csv_file.add_header('Content-Disposition', 'attachment',
         filename=csvfile + ".zip")

msg.attach(csv_file)

From this This user's most upvoted answer I could fix the read() takes at least 2 arguments error I'm receiving by doing a normal open() operation on the zip file but since this file is a buffered stream that doesn't work.

I'm not sure how else to load the zipfile object into the set_payload but that should also work I would think.



Solution 1:[1]

The read method of a ZipFile object is meant to read the content of a named file within the zip file.

You should use the content of buffer instead after you write to the buffer with the writestr method of the ZipFile instance:

csv_file.set_payload(buffer.getvalue())

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 blhsing