5

Running a line like:

s3_obj = boto3.resource('s3').Object(bucket, key)
s3_obj.meta.client.generate_presigned_url('get_object', ExpiresIn=0, Params={'Bucket':bucket,'Key':key})

Yields a result like:

https://my-bucket.s3.amazonaws.com/my-key/my-object-name?AWSAccessKeyId=SOMEKEY&Expires=SOMENUMBER&x-amz-security-token=SOMETOKEN

For an s3 object with public-read ACL, all the GET params are unnecessary.

I could cheat and use rewrite the URL without the GET params but that feels unclean and hacky.

How do I use boto3 to provide me with just the public link, e.g. https://my-bucket.s3.amazonaws.com/my-key/my-object-name? In other words, how do I skip the signing step in generate_presigned_url? I don't see anything like a generated_unsigned_url function.

wonton
  • 7,568
  • 9
  • 56
  • 93

1 Answers1

8

The best solution I found is still to use the generate_presigned_url, just that the Client.Config.signature_version needs to be set to botocore.UNSIGNED.

The following returns the public link without the signing stuff.

config.signature_version = botocore.UNSIGNED
boto3.client('s3', config=config).generate_presigned_url('get_object', ExpiresIn=0, Params={'Bucket': bucket, 'Key': key})

The relevant discussions on the boto3 repository are:

wonton
  • 7,568
  • 9
  • 56
  • 93
  • 1
    You should include what config is defined to be: `s3 = boto3.client('s3')` and `config = s3._client_config`. – Shmack Feb 23 '22 at 05:30