1

I have a Flask-based webapp that I'm trying to do everything in-memory without touching the disk at all.

I have created an in-memory Word doc (using python-docx library) and an in-memory Excel file (using openpyxl). They are both of type BytesIO. I want to return them both with Flask, so I want to zip them up and return the zipfile to the user's browser.

My code is as follows:

inMemory = io.BytesIO()
zipfileObj = zipfile.ZipFile(inMemory, mode='w', compression=zipfile.ZIP_DEFLATED)
    try:
        print('adding files to zip archive')
        zipfileObj.write(virtualWorkbook)
        zipfileObj.write(virtualWordDoc)

When the zipfile tries to write the virtualWorkbook I get the following error: {TypeError}stat: path should be string, bytes, os.PathLike or integer, not BytesIO

I have skimmed the entirety of the internet but have come up empty-handed, so if someone could explain what I'm doing wrong that would be amazing

  • https://stackoverflow.com/a/44946732/2834978 – LMC Aug 12 '21 at 00:30
  • 1
    `ZipFile` accepts a file-like object; `ZipFile.write` wants the actual bytes: the contents of the virtual document, not the virtual document itself. – chepner Aug 12 '21 at 00:32

2 Answers2

0

Seems like it's easier to mount tmpfs/ramdisk/smth to a specific directory like here, and just use tempfile.NamedTemporaryFile() as usual.

madbird
  • 1,326
  • 7
  • 11
-1

You could use the writestr method. It accepts both string and bytes.

zipfileObj.write(zipfile.ZipInfo('folder/name.docx'),
                                  virtualWorkbook.read())
fgui
  • 1,564
  • 1
  • 13
  • 14