Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boto3 get only S3 buckets of specific region

The following code sadly lists all buckets of all regions and not only from "eu-west-1" as specified. How can I change that?

import boto3

s3 = boto3.client("s3", region_name="eu-west-1")

for bucket in s3.list_buckets()["Buckets"]:

    bucket_name = bucket["Name"]
    print(bucket["Name"])
like image 621
lony Avatar asked Apr 13 '18 09:04

lony


People also ask

Can I access S3 bucket from different region?

S3 Multi-Region Access Points provide a single global endpoint to access a data set that spans multiple S3 buckets in different AWS Regions. This allows you to build multi-region applications with the same simple architecture used in a single region, and then to run those applications anywhere in the world.

Is S3 bucket global or region specific?

While the name space for buckets is global, S3 (like most of the other AWS services) runs in each AWS region (see the AWS Global Infrastructure page for more information).

Why does S3 not need Region selection?

But when we create S3 in AWS console in "Global" it says "S3 does not require a region selection" because it shows all the buckets in all the regions as it is the user interface and this is the reason why you can't create the bucket with same names as it may lead to conflicts between addresses.


2 Answers

s3 = boto3.client("s3", region_name="eu-west-1")

connects to S3 API endpoint in eu-west-1. It doesn't limit the listing to eu-west-1 buckets. One solution is to query the bucket location and filter.

s3 = boto3.client("s3")

for bucket in s3.list_buckets()["Buckets"]:
    if s3.get_bucket_location(Bucket=bucket['Name'])['LocationConstraint'] == 'eu-west-1':
        print(bucket["Name"])

If you need a one liner using Python's list comprehension:

region_buckets = [bucket["Name"] for bucket in s3.list_buckets()["Buckets"] if s3.get_bucket_location(Bucket=bucket['Name'])['LocationConstraint'] == 'eu-west-1']
print(region_buckets)
like image 182
helloV Avatar answered Oct 20 '22 18:10

helloV


The solution above does not always work for buckets in some US regions because the 'LocationConstraint' can be null. Here is another solution:

s3 = boto3.client("s3")

for bucket in s3.list_buckets()["Buckets"]:
    if s3.head_bucket(Bucket=bucket['Name'])['ResponseMetadata']['HTTPHeaders']['x-amz-bucket-region'] == 'us-east-1':
        print(bucket["Name"])

The SDK method:

s3.head_bucket(Bucket=[INSERT_BUCKET_NAME_HERE])['ResponseMetadata']['HTTPHeaders']['x-amz-bucket-region']

... should always give you the bucket region. Thanks to sd65 for the tip: https://github.com/boto/boto3/issues/292

like image 37
James Shapiro Avatar answered Oct 20 '22 17:10

James Shapiro