Download files from public S3 bucket with boto3
<p>I cannot download a file or even get a listing of the <strong>public</strong> S3 bucket with <code>boto3</code>.</p>

<p>The code below works with my own bucket, but not with public one:</p>

<pre><code>def s3_list(bucket, s3path_or_prefix):
    bsession = boto3.Session(aws_access_key_id=settings.AWS['ACCESS_KEY'],
                             aws_secret_access_key=settings.AWS['SECRET_ACCESS_KEY'],
                             region_name=settings.AWS['REGION_NAME'])
    s3 = bsession.resource('s3')
    my_bucket = s3.Bucket(bucket)
    items = my_bucket.objects.filter(Prefix=s3path_or_prefix)
    return [ii.key for ii in items]
</code></pre>

<p>I get an <code>AccessDenied</code> error on this code. The bucket is not in my own and I cannot set permissions there, but I am sure it is open to public read.</p>

<p>I had the similar issue in the past. I have found a key to this bug in <a href="https://github.com/boto/boto3/issues/134" rel="nofollow">https://github.com/boto/boto3/issues/134</a> .</p>

<p>You can use undocumented trick:</p>

<pre><code>import botocore


def s3_list(bucket, s3path_or_prefix, public=False):
    bsession = boto3.Session(aws_access_key_id=settings.AWS['ACCESS_KEY'],
                             aws_secret_access_key=settings.AWS['SECRET_ACCESS_KEY'],
                             region_name=settings.AWS['REGION_NAME'])
    client = bsession.client('s3')
    if public:
        client.meta.events.register('choose-signer.s3.*', botocore.handlers.disable_signing)
    result = client.list_objects(Bucket=bucket, Delimiter='/', Prefix=s3path_or_prefix)
    return [obj['Prefix'] for obj in result.get('CommonPrefixes')]
</code></pre>

python boto3