By default all the objects in an AWS bucket are private. Sometimes we may come across the requirement to share an object (file) present in s3 to others and don’t want to share aws access credentials.

In these scenarios, AWS provides a simple way to provide access by generating a timebound signed URLs using the access credentials. These URLs will be active only for the specified time period and the access will be revoked after that time period. I came across a similar requirement and the solution is shared below.

import boto3
from urlparse import urlparse
__aws_access_key__ = "XXXXXXXXXXXXXXX"
__aws_secret_key__ = "XXXXXXXXXXXXX"
def s3_client():
"""
This method establishes the connection to S3.
:return: s3 client
"""
s3_client = boto3.client('s3', aws_access_key_id=__aws_access_key__,
aws_secret_access_key=__aws_secret_key__)
return s3_client
def presign_s3(bucket, key, expiration=3600):
"""
Function to generate presigned URL on S3 (Default 1 hour expiration)
"""
params = {
'Bucket': bucket,
'Key': key
}
s3_conn = s3_client()
signed_url = s3_conn.generate_presigned_url('get_object', Params=params, ExpiresIn=expiration)
return signed_url
def parse_s3_url(s3_url):
"""
This function parses the S3 URL and returns the S3 bucket name & Key path
:param s3_url:
:return: bucketname, keypath
"""
url_parts = urlparse(s3_url)
bucket_name = url_parts.netloc
key_path = url_parts.path
if key_path.startswith('/'):
key_path = key_path.lstrip("/")
return bucket_name, key_path
def main(s3_url, expiration):
"""
Main method
:param s3_url:
:param expiration:
:return:
"""
bucket_name, key_path = parse_s3_url(s3_url)
signed_url = presign_s3(bucket_name, key_path, expiration)
return signed_url
if __name__ == '__main__':
main("s3://amalgjose/sampledata.txt", 60)