Generate Zip Files and Store in GAE BlobStore
Asked Answered
E

1

7

I am trying to generate a zip file and store in App Engine's Blobstore. Right now, I do not get a valid zip file from the Blobstore. Not sure the problem is with zipping, storing, retrieving or downloading.

I have built the code based on snippets from the following questions.

After storing in Blobstore, I let users download it through a Flask application.

Here is the gist of what I am trying to do.

def zipit():
  zipstream = StringIO.StringIO()
  zfile = zipfile.ZipFile(file=zipstream, mode='w')
  bytes = "lorem ipsum dolor sit amet"
  zfile.writestr('loremipsum', bytes, compress_type=zipfile.ZIP_STORED)
  zfile.close()
  zipstream.seek(0)
  return zipstream.getvalue()


zip_file = files.blobstore.create(mime_type='application/zip')
zip_data = zipit()

with files.open(zip_file, 'a') as f:
  f.write(zip_data)
files.finalize(zip_file)
blob_key = files.blobstore.get_blob_key(zip_file)

blob_data = blobstore.BlobReader(blob_key).read()

# http://flask.pocoo.org/docs/api/
response = make_response(blob_data)
response.headers['Content-Type'] = 'application/zip'
response.headers['Content-Disposition'] = 'attachment; filename="loremipsum.zip"'
return response

Any help is much appreciated.

Eristic answered 20/2, 2012 at 19:15 Comment(0)
C
6

Most of your code works for me in a webapp handler in dev_appserver.py. My version below serves the zip file directly out of the Blobstore, vs. trying to read it into app instance RAM and serve it. Maybe this is what you intended? If not, continue looking for the problem in your code that reads and serves the value, because I believe you're creating a valid Zip file in the Blobstore.

#!/usr/bin/env python

import StringIO
import zipfile
from google.appengine.api import files
from google.appengine.ext import blobstore
from google.appengine.ext import webapp
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext.webapp import util

def zipit():
    zipstream = StringIO.StringIO()
    zfile = zipfile.ZipFile(file=zipstream, mode='w')
    bytes = "lorem ipsum dolor sit amet"
    zfile.writestr('loremipsum', bytes, compress_type=zipfile.ZIP_STORED)
    zfile.close()
    zipstream.seek(0)
    return zipstream.getvalue()

class MainHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self):
        k = self.request.get('key')
        if k:
            self.send_blob(k)
            return

        zip_file = files.blobstore.create(mime_type='application/zip')
        zip_data = zipit()

        with files.open(zip_file, 'a') as f:
            f.write(zip_data)
        files.finalize(zip_file)
        blob_key = files.blobstore.get_blob_key(zip_file)

        self.response.out.write('<a href="/getzip?key=%s">get zip</a>' % blob_key)


application = webapp.WSGIApplication([('/getzip', MainHandler)])

def main():
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()
Cavorelievo answered 21/2, 2012 at 1:56 Comment(3)
Thanks! Your code works. Probably it is getting corrupted during the retrieval. The program is built on Flask, and that's the reason, why I read the file and serve. I tried send_blob, but it requires the headers to be available. I will have to find some workarounds to serve the blob file directly through the Flask framework.Eristic
It looks like this is a problem of who gets to handle the URLs. For images in blobstore there is get_serving_url. I am yet to find out how to serve files from blobstore, through Flask.Eristic
Another step. response = make_response() response.headers['X-AppEngine-BlobKey'] = blob_key response.headers['Content-Type'] = 'application/zip' response.headers['Content-Disposition'] = 'attachment; filename="loremipsum.zip"' return response But this does not solve the original problem still!Eristic

© 2022 - 2024 — McMap. All rights reserved.