Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload image available at public URL to S3 using boto

I'm working in a Python web environment and I can simply upload a file from the filesystem to S3 using boto's key.set_contents_from_filename(path/to/file). However, I'd like to upload an image that is already on the web (say https://pbs.twimg.com/media/A9h_htACIAAaCf6.jpg:large).

Should I somehow download the image to the filesystem, and then upload it to S3 using boto as usual, then delete the image?

What would be ideal is if there is a way to get boto's key.set_contents_from_file or some other command that would accept a URL and nicely stream the image to S3 without having to explicitly download a file copy to my server.

def upload(url):     try:         conn = boto.connect_s3(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)         bucket_name = settings.AWS_STORAGE_BUCKET_NAME         bucket = conn.get_bucket(bucket_name)         k = Key(bucket)         k.key = "test"         k.set_contents_from_file(url)         k.make_public()                 return "Success?"     except Exception, e:             return e 

Using set_contents_from_file, as above, I get a "string object has no attribute 'tell'" error. Using set_contents_from_filename with the url, I get a No such file or directory error . The boto storage documentation leaves off at uploading local files and does not mention uploading files stored remotely.

like image 637
dgh Avatar asked Jan 15 '13 20:01

dgh


People also ask

Can you upload to public S3 bucket?

You can have an unlimited number of objects in a bucket. Before you can upload files to an Amazon S3 bucket, you need write permissions for the bucket. For more information about access permissions, see Identity and access management in Amazon S3. You can upload any file type—images, backups, data, movies, etc.

How can I access S3 files in Python using urls?

http://s3tools.org/s3cmd works pretty well and support the s3:// form of the URL structure you want. It does the business on Linux and Windows. If you need a native API to call from within a python program then http://code.google.com/p/boto/ is a better choice.


1 Answers

Here is how I did it with requests, the key being to set stream=True when initially making the request, and uploading to s3 using the upload.fileobj() method:

import requests import boto3  url = "https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg" r = requests.get(url, stream=True)  session = boto3.Session() s3 = session.resource('s3')  bucket_name = 'your-bucket-name' key = 'your-key-name' # key is the name of file on your bucket  bucket = s3.Bucket(bucket_name) bucket.upload_fileobj(r.raw, key) 
like image 199
blaklaybul Avatar answered Sep 18 '22 12:09

blaklaybul