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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
Nice one