Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3 Boto 3, AWS S3: Get object URL

I need to retrieve an public object URL directly after uploading a file, this to be able to store it in a database. This is my upload code:

   s3 = boto3.resource('s3')
   s3bucket.upload_file(filepath, objectname, ExtraArgs={'StorageClass': 'STANDARD_IA'})

I am not looking for a presigned URL, just the URL that always will be publicly accessable over https.

Any help appreciated.

like image 607
HyperDevil Avatar asked Feb 04 '18 13:02

HyperDevil


People also ask

What is S3 object URL?

An S3 bucket can be accessed through its URL. The URL format of a bucket is either of two options: http://s3.amazonaws.com/[bucket_name]/ http://[bucket_name].s3.amazonaws.com/ So, if someone wants to test the openness of a bucket, all they have to do is hit the bucket's URL from a web browser.

What is Presigned S3 URL?

A user who does not have AWS credentials or permission to access an S3 object can be granted temporary access by using a presigned URL. A presigned URL is generated by an AWS user who has access to the object. The generated URL is then given to the unauthorized user.

How do I get pre-signed URL S3?

Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that contains the object that you want a presigned URL for. In the Objects list, select the object that you want to create a presigned URL for.


2 Answers

There's no simple way but you can construct the URL from the region where the bucket is located (get_bucket_location), the bucket name and the storage key:

bucket_name = "my-aws-bucket"
key = "upload-file"

s3 = boto3.resource('s3')
bucket = s3.Bucket(bucket_name)
bucket.upload_file("upload.txt", key)
location = boto3.client('s3').get_bucket_location(Bucket=bucket_name)['LocationConstraint']
url = "https://s3-%s.amazonaws.com/%s/%s" % (location, bucket_name, key)
like image 106
ofrommel Avatar answered Sep 26 '22 05:09

ofrommel


Since 2010 you can use a virtual-hosted style S3 url, i.e. no need to mess with region specific urls:

url = f'https://{bucket}.s3.amazonaws.com/{key}'

With quoted key :

url = f'''https://{bucket}.s3.amazonaws.com/{urllib.parse.quote(key, safe="~()*!.'")}'''

Moreover, support for the path-style model (region specific urls) continues for buckets created on or before September 30, 2020. Buckets created after that date must be referenced using the virtual-hosted model.

See also this blog post.

like image 26
lionels Avatar answered Sep 26 '22 05:09

lionels