54

I am saving a key to a bucket with:

    key = bucket.new_key(fileName)
    key.set_contents_from_string(base64.b64decode(data))
    key.set_metadata('Content-Type', 'image/jpeg')
    key.set_acl('public-read')

After the save is successful, how can I access the URL of the newly created file?

S-K'
  • 2,968
  • 7
  • 33
  • 46

3 Answers3

98

If the key is publicly readable (as shown above) you can use Key.generate_url:

url = key.generate_url(expires_in=0, query_auth=False)

If the key is private and you want to generate an expiring URL to share the content with someone who does not have direct access you could do:

url = key.generate_url(expires_in=300)

where expires is the number of seconds before the URL expires. These will produce HTTPS url's. If you prefer an HTTP url, use this:

url = key.generate_url(expires_in=0, query_auth=False, force_http=True)
foresmac
  • 125
  • 2
  • 8
garnaat
  • 37,899
  • 7
  • 109
  • 98
  • 13
    With boto 2.9.6 I had to use `expires_in=0`. `expires_in=None` gave me an error. – Dirk Jun 26 '13 at 21:09
  • 4
    Worth noting that `expires_in=0` is "expires right now!" in boto 2.3.0 – Dragon Dave Dec 06 '13 at 11:54
  • 3
    If the key is public (for example, you call make_public()), expires_in=0 does nothing -> the url generated by generate_url will never expire. In boto 2.2.2, generate_url(expires_in=None) throws an error because tries to calculate expiration date as "expires = int(time.time() + expires_in)" – Alberto Megía Mar 06 '14 at 12:16
  • I typically reach for the [``S3Connection.generate_url``](http://boto.readthedocs.org/en/latest/ref/s3.html#boto.s3.connection.S3Connection.generate_url) method if all I need to do is quickly generate a link. See an example here: https://coderwall.com/p/02lxqw – Seth Nov 03 '14 at 01:07
  • 3
    @Seth that link is to boto, not boto3. This question is about boto3. – dsjoerg Dec 04 '15 at 20:27
31

For Boto3, you need to do it the following way...

import boto3

s3 = boto3.client('s3')
url = '{}/{}/{}'.format(s3.meta.endpoint_url, bucket, key)
treecoder
  • 36,160
  • 18
  • 57
  • 89
8
import boto
from boto.s3.connection import S3Connection

conn = S3Connection('AWS_ACCESS_KEY', 'AWS_SECRET_KEY')

secure_https_url = 'https://{host}/{bucket}/{key}'.format(
    host=conn.server_name(),
    bucket='name-of-bucket',
    key='name_of_key')

http_url = 'http://{bucket}.{host}/{key}'.format(
    host=conn.server_name(),
    bucket='name-of-bucket',
    key='name_of_key')

That's how I did it in boto 2.23.0 for a public URL. I couldn't get the expires_in=None argument to work.

Note that for HTTPS you can't use a subdomain.

kumar303
  • 638
  • 5
  • 7
  • This works great and doesn't require a call to the S3 API. Thank you for including the HTTPS URL, too. – Seth Feb 17 '14 at 18:17
  • 1
    None of the approaches described here require a call to the S3 API. Some do require you to have boto installed and if the object you are linking to is publicly accessible you can avoid that by using the approach shown above. – garnaat Mar 06 '14 at 12:48
  • You can use a subdomain if the bucket name only matches a valid subdomain: only lower case letters, numbers, and dashes. In your example, if the bucket really were "name-of-bucket" you could use the same code for `http_url`, just exchanging https for http. – Jordan Reiter May 13 '15 at 19:19