views:

866

answers:

3

I have a small project that would be perfect for Google App Engine. Implementing it hinges on the ability to generate a ZIP file and return it.

Due to the distributed nature of App Engine, from what I can tell, the ZIP file couldn't be created "in-memory" in the traditional sense. It would basically have to be generated and and sent in a single request/response cycle.

Does the Python zip module even exist in the App Engine environment?

+2  A: 

From What is Google App Engine:

You can upload other third-party libraries with your application, as long as they are implemented in pure Python and do not require any unsupported standard library modules.

So, even if it doesn't exist by default you can (potentially) include it yourself. (I say potentially because I don't know if the Python zip library requires any "unsupported standard library modules".

JMD
+16  A: 

zipfile is available at GAE and example of its use exactly like yours was copied here from http://www.tareandshare.com/2008/09/28/Zip-Google-App-Engine-GAE/

from google.appengine.ext import webapp
from google.appengine.api import urlfetch
import zipfile

def addFile(self,zipstream,url,fname):
    # get the contents   
    result = urlfetch.fetch(url)

    # store the contents in a stream
    f=StringIO(result.content)
    length = result.headers['Content-Length']
    f.seek(0)

    # write the contents to the zip file
    while True:
    buff = f.read(int(length))
    if buff=="":break
    zipstream.writestr(fname,buff)
    return zipstream

def ZipFiles(self):
    # create the zip stream
    zipstream=StringIO()
    file = zipfile.ZipFile(zipstream,"w")

    url = 'http://someplace.tld/outimage.jpg'

    # repeat this for every URL that should be added to the zipfile
    file =self.addFile(file,url,"ourimage.jpg")

    # we have finished with the zip so package it up and write the directory
    file.close()
    zipstream.seek(0)

    # create and return the output stream
    self.response.headers['Content-Type'] ='application/zip'
    self.response.headers['Content-Disposition'] = 'attachment; filename="outfile.zip"' 
    while True:
    buf=zipf.read(2048)
    if buf=="": break
    self.response.out.write(buf)
myroslav
A: 
import zipfile
import StringIO

text = u"ABCDEFGHIJKLMNOPQRSTUVWXYVabcdefghijklmnopqqstuvweyxáéöüï东 廣 広 广 國 国 国 界"

zipstream=StringIO.StringIO()
file = zipfile.ZipFile(file=zipstream,compression=zipfile.ZIP_DEFLATED,mode="w")
file.writestr("data.txt.zip",text.encode("utf-8"))
file.close()
zipstream.seek(0)
self.response.headers['Content-Type'] ='application/zip'
self.response.headers['Content-Disposition'] = 'attachment; filename="data.txt.zip"'
self.response.out.write(zipstream.getvalue())