Можно ли сгенерировать и вернуть ZIP-файл с помощью App Engine?

У меня есть небольшой проект, который идеально подошел бы для Google App Engine. Реализация этого зависит от возможности генерировать ZIP-файл и возвращать его.

Из-за распределенной природы App Engine, насколько я могу судить, ZIP-файл нельзя было создать «в памяти» в традиционном смысле. По сути, его нужно было бы сгенерировать и отправить за один цикл запроса / ответа.

Существует ли вообще модуль Python zip в среде App Engine?

Ответов (3)

Решение

zipfile доступен на appengine, и его переработанный пример приведен ниже:

from contextlib import closing
from zipfile import ZipFile, ZIP_DEFLATED

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

def addResource(zfile, url, fname):
    # get the contents      
    contents = urlfetch.fetch(url).content
    # write the contents to the zip file
    zfile.writestr(fname, contents)

class OutZipfile(webapp.RequestHandler):
    def get(self):
        # Set up headers for browser to correctly recognize ZIP file
        self.response.headers['Content-Type'] ='application/zip'
        self.response.headers['Content-Disposition'] = \
            'attachment; filename="outfile.zip"'    

        # compress files and emit them directly to HTTP response stream
        with closing(ZipFile(self.response.out, "w", ZIP_DEFLATED)) as outfile:
            # repeat this for every URL that should be added to the zipfile
            addResource(outfile, 
                'https://www.google.com/intl/en/policies/privacy/', 
                'privacy.html')
            addResource(outfile, 
                'https://www.google.com/intl/en/policies/terms/', 
                'terms.html')

Из Что такое Google App Engine :

Вы можете загружать в свое приложение другие сторонние библиотеки, если они реализованы на чистом Python и не требуют каких-либо неподдерживаемых стандартных библиотечных модулей.

Таким образом, даже если он не существует по умолчанию, вы можете (потенциально) включить его самостоятельно. (Я говорю потенциально», потому что не знаю, требуются ли для библиотеки Python zip какие-либо «неподдерживаемые стандартные библиотечные модули».

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())