An exception occurred : 's3.ServiceResource' object has no attribute 'head_object'

Question:

I am checking if an object exist in S3 bucket.
Following is the code snippet that I am using.
obj is the filename.

    s3 = boto3.resource('s3')
    try:
        s3.head_object(Bucket=bucket_name, Key=obj)
    except ClientError as e:
        return False

But it is throwing me exception :

An exception occurred in python_code : 's3.ServiceResource' object has no attribute 'head_object'

Reference I used for this API – https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.head_object

Could anyone help me fix this?

Asked By: gkr2d2

||

Answers:

Try:

s3 = boto3.client('s3')

instead of

s3 = boto3.resource('s3')

Answered By: Ntwobike

I am bundeling a detailed response here:

1. boto3.client("s3") will allow you to perform Low level API calls
2. boto3.resource('s3') will allow you to perform High level API calls

Read here: Difference in boto3 between resource, client, and session?

Your requirement/operation requires an action on a bucket rather on a object/resource in the bucket. So here, it make sense and that is how AWS people have differentiated here API calls wrapper in the above mentined client methods

That is the reason why here boto3.client("s3") comes in picture.

Answered By: Varun Singh

The boto3 resource and client APIs are different. Since you instantiated a boto3.resource("s3") object, you must use methods available to that object. head_object() is not available to the resource but is available to the client. The other answers provided detail how if you switch to using the client API, you can then use the head_object() method. If you are using the resource API in the rest of the codebase, please note you can check whether items exist in a Bucket, it is just done a little differently. The example given in the Boto3 docs is:

import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket('my-bucket')
for obj in bucket.objects.all():
    print(obj.key)  # Change this to check membership, etc.

Why use resource()? You do not have to make a second API call to get the objects! They’re available to you as a collection on the bucket (via buckets.objects).

Answered By: Nathan
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.