[Solved]-Download files from Amazon S3 with Django

14👍

If you don’t want the files to be downloadable, set ACL to be private (only accessible via your account). Your users will be still able to download file is you provide them with signed URL. When you sign a URL, you generate token with expire time. You can set it to something reasonable as 10 minutes. Use Amazon Web Services interface for Python — Boto.

import boto
conn = boto.connect_s3('<aws access key>', '<aws secret key>')
bucket = conn.get_bucket('your_bucket')
s3_file_path = bucket.get_key('path/to/file')
url = s3_file_path.generate_url(expires_in=600) # expiry time is in seconds

return HttpResponseRedirect(url)

Note, that this is safe, as token is only valid only for one request method (GET by default) and only for one file. So there is no risk of someone reusing the token for example download other files or manipulate the file given.

👤vartec

10👍

I couldn’t easily find anywhere that specified how to do this and ended up back at this question time and again when I searched. So

With django-storages using the boto backend, the way to do this is something like

filepath = settings.MEDIA_DIRECTORY + file.name
response_headers = {
    'response-content-type': 'application/force-download',
    'response-content-disposition':'attachment;filename="%s"'%file.name
    }
url = s3.generate_url(60, 'GET',
                bucket=settings.AWS_STORAGE_BUCKET_NAME,
                key=filepath,
                response_headers=response_headers,
                force_http=True)
return http.HttpResponseRedirect(url)
👤so_

5👍

The answers above are outdated since they use boto instead of boto3. This is how it is done with boto3:

import boto3

client = boto3.client('s3', aws_access_key_id = config('AWS_ACCESS_KEY_ID'), /
aws_secret_access_key = config('AWS_SECRET_ACCESS_KEY'))
bucket_name = config('AWS_STORAGE_BUCKET_NAME')
file_name = settings.AWS_MEDIA_LOCATION + '/' + 'file-name'

url = client.generate_presigned_url(
                                    'get_object', 
                                    Params = { 
                                                'Bucket': bucket_name, 
                                                'Key': file_name, }, 
                                    ExpiresIn = 600, )
return HttpResponseRedirect(url)

Leave a comment