Home > Software design >  S3 Client has no attribute called Bucket
S3 Client has no attribute called Bucket

Time:03-27

I'm trying to download folder from my s3 bucket. I want to use s3.client because I have used client method further in the code but I'm not able to access the bucket using client method. When I use "s3Client.Bucket(bucketName)" I get an error saying it has no attribute Bucket. When I use "s3Client.get_object(Bucket=bucketName, Key= ?)" first it said key is required, what should be the key, is it the folder I want to download? Please let me know what am I doing wrong here. Thank you.

awsParams = {
    "bucket_name": "asgard-icr-model",
    "region_name": "ap-south-1"
}

def get_s3_client():

    s3Client = boto3.client('s3')
    return s3Client

def download_from_s3(srcDir, dstDir):

    try:

        bucketName = awsParams['bucket_name'] #s3 bucket name

        s3Client = get_s3_client()
        bucket = s3Client.Bucket(bucketName) # I get error saying - client has no attribute Bucket.
        bucket = s3Client.get_object(Bucket=bucketName, Key= ?) # If I use this line instead of previous, what should be my key here? 

So now if I do this change, what should I use instead of list_objects_v2() in s3.resource as there is no attribute with this name?

def get_s3_object():

    s3Obj = boto3.resource("s3",region_name=awsParams['region_name'])
    
    return s3Obj

def download_from_s3(srcDir, dstDir):

    try:

        bucketName = awsParams['bucket_name'] #s3 bucket name
        
        # s3Client = get_s3_client()
        # bucket = s3Client.Bucket(bucketName)
        # bucket = s3Client.get_object(Bucket=bucketName, Key=)
        s3Obj = get_s3_object()
        bucket = s3Obj.Bucket(bucketName)


        keys = []
        dirs = []
        next_token = ''

        base_kwargs = {
            'Bucket':bucket,
            'srcDir':srcDir,
        }
        
        while next_token is not None:
            kwargs = base_kwargs.copy()
            if next_token != '':
                kwargs.update({'ContinuationToken': next_token})
            **results = s3Client.list_objects_v2(**kwargs)**
            contents = results.get('Contents')
            for i in contents:
                k = i.get('Key')
                if k[-1] != '/':
                    keys.append(k)
                else:
                    dirs.append(k)
            next_token = results.get('NextContinuationToken')
        for d in dirs:
            dest_pathname = os.path.join(local, d)
            if not os.path.exists(os.path.dirname(dest_pathname)):
                os.makedirs(os.path.dirname(dest_pathname))
        for k in keys:
            dest_pathname = os.path.join(local, k)
            if not os.path.exists(os.path.dirname(dest_pathname)):
                os.makedirs(os.path.dirname(dest_pathname))
            s3Client.download_file(bucket, k, dest_pathname)
            
    except Exception as e:
        raise

CodePudding user response:

You should be using a resource, not client:

s3Resource = boto3.resource('s3')
return s3Resource

end then

bucket = s3Resource.Bucket(bucketName)

CodePudding user response:

When using a client, you can obtain a list of objects with:

s3_client = boto3.client('s3')

results = s3_client.list_objects_v2(Bucket=...)

for object in results['Contents']:
    print(object['Key'])

When using a resource, you can use:

s3_resource = boto3.resource('s3')

bucket = s3_resource.Bucket('Bucketname')

for object in bucket.objects.all():
    print(object.key)
  • Related