Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload Images to Amazon S3 using Django

I'm currently resizing images on the fly when a user uploads a picture. The original picture is stored on Amazon S3 in a bucket called djangobucket. Inside this bucket, contains thousands of folders.

Each folder is named after the user. I don't have to worry about bucket creation or folder creation since all of that is handled from the client side.

Here is a diagram:

djangobucket  ------------> bob ---------> picture1.jpg
                                           picture2.jpg
                                           picture3.jpg
                                           picture4.jpg

As you can see, Bob has many pictures. Once a user uploads a picture to S3, I download it through Django via a URL, in this case it would be: http://s3.amazonaws.com/djangobucket/bob/picture1.jpg

I download the image and perform image processing and save the processed image on my django app server.

I would like to send this processed image back into bob's folder so that it can be publicly reached at http://s3.amazonaws.com/djangobucket/bob/picture1_processed.jpg

The client already has access to the amazon key and secret key so that he or she can upload pictures to this bucket. All users on the service use the same keys. I too will be using the same keys.

I've heard of something called Boto, but it involves Bucket creation and I'm unsure of how to do just the uploading part. I'm only concerned about uploading the picture to the appropriate user folder.

I've been researching this for hours so I've turned to the experts here.

Here is my code, just so that you can get a better understanding of what I'm doing.

user = 'bob'

url = 'http://s3.amazonaws.com/djangobucket/bob/picture1.jpg'
filename = url.split('/')[-1].split('.')[0]

download_photo = urllib.urlretrieve(url, "/home/ubuntu/Desktop/Resized_Images/%s.jpg" % (filename))
downloaded_photo = Image.open("/home/ubuntu/Desktop/Resized_Images/%s.jpg" % (filename))

resized_photo = downloaded_photo.resize((300, 300), Image.ANTIALIAS)
new_filename = filename + "_processed"

resized_photo.save("/home/ubuntu/Desktop/Resized_Images/%s.jpg" % (new_filename)) 

I would like to send the resized photo saved in /home/ubuntu/Desktop/Resized_Images/ to Bob's folder in the djangobucket on Amazon S3 and make it publicly visible.

Thanks for your help.

EDIT I found this link: http://www.laurentluce.com/posts/upload-and-download-files-tofrom-amazon-s3-using-pythondjango/

Not quite how to use it for my case, but I think I'm on the right track.

like image 555
deadlock Avatar asked Sep 10 '13 21:09

deadlock


1 Answers

boto is the best way to do this.

You can get an existing bucket using:

get_bucket(bucket_name, validate=True, headers=None)

After installing boto, this code should do what you need to do

from boto.s3.connection import S3Connection
from boto.s3.key import Key

conn = S3Connection('<aws access key>', '<aws secret key>')
bucket = conn.get_bucket('<bucket name>')
k = Key(bucket)
k.key = 'file_path_on_s3' # for example, 'images/bob/resized_image1.png'
k.set_contents_from_file(resized_photo)

Here are some links to the Boto API and Boto S3 Doc

like image 194
epau Avatar answered Oct 13 '22 11:10

epau