Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does it support zipping multiple S3 objects and sending to Django response stream without downloading locally? #11

Open
aamironline opened this issue Nov 2, 2020 · 3 comments

Comments

@aamironline
Copy link

If yes, can you provide an example? Any issues?

@aamironline aamironline changed the title Does it support zipping multiple S3 objects without downloading locally? Does it support zipping multiple S3 objects and sending to Django response stream without downloading locally? Nov 2, 2020
@arjan-s
Copy link
Owner

arjan-s commented Nov 2, 2020

I'm afraid that functionality would be outside of the scope of this package. However, zipstream does support streaming input files. So if you have an S3 library that can stream the data instead of storing it locally, you can probably use those streams as inputs for zipstream and then stream the zipped output to the browser. In that case, the data would never touch your server's disk.

@gassc
Copy link

gassc commented Jul 21, 2021

The approach below worked for me. It relies on using requests with signed URLs from S3, but I imagine the same can be achieved with S3.Client.download_fileobj in boto3.

some_list_of_files_to_get_from_s3 = [
    (<s3 signed url>, '<name of file>'),
    ...
]

z = zipstream.ZipFile(mode="w", compression=zipstream.ZIP_DEFLATED)

for each_s3_signed_url, file_name in some_list_of_files_to_get_from_s3:
    with requests.get(each_s3_signed_url, stream=True) as r:
        z.writestr(file_name, r.content) # this worked for me
        # tried the following but could not get it to write data to the files in the zip archive:
        # z.write_iter(file_name, r.iter_content())

With Django, it was then matter of passing z into StreamingHttpResponse to round out the view code:

response = StreamingHttpResponse(z, content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=archive.zip'
return response

Hope it helps.

@1oglop1
Copy link

1oglop1 commented Nov 23, 2021

@gassc Thank you for your comment, I'm just solving a similar problem.
Do you know if your approach can work the same way with Django-storages, I know it's using boto under the hood but not much else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants