2

Trying to read a file from a bucket in s3. The bucket has a trigger wired to a python lambda function. This then runs when a new file is put in the bucket. I keep getting an error.

This the code:

Download the file from S3 to the local filesystem

try:
    s3.meta.client.download_file(bucket, key, localFilename)
except Exception as e:
    print(e)
    print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
    raise e

I get this error

'ClientMeta' object has no attribute 'client'

I am thinking it could be the IAM but the Lambda function has the AWSLambdaFullAccess Role which is pretty much an admin in S3.

Any help would be much appreciated

Red
  • 45
  • 1
  • 3
  • It looks to me as if `s3.meta` doesn't have the `client` object, so the call above is failing before even getting to AWS. I'm guessing the exception is an `AttributeError`? Please edit your question to include where the variable `s3` gets its value from. Please also include the full traceback. – Luke Woodward Nov 19 '17 at 13:32
  • 1
    Why don't you use boto3 s3 low level client to download the file. `import boto3 # Get the service client s3 = boto3.client('s3') # Download object at bucket-name with key-name to tmp.txt s3.download_file("bucket-name", "key-name", "tmp.txt")` . – Usman Azhar Nov 19 '17 at 13:39

2 Answers2

3

This error is caused by creating a boto3 client instead of resource.

Example (this will reproduce your error):

s3 = boto3.client('s3')
s3.meta.client.download_file(bucket, key, localFilename)

You have two solutions:

1) Change to use the "high-level abstracted" s3 resource:

s3 = boto3.resource('s3')
s3.meta.client.download_file(bucket, key, localFilename)

2) Directly use the "low-level" s3 client download_file()

s3 = boto3.client('s3')
s3.download_file(bucket, key, localFilename)

Working with Boto3 Low-Level Clients

John Hanley
  • 74,467
  • 6
  • 95
  • 159
0

I think may be refer incorrectly object type for variable s3. s3.meta.client may be something you use when s3 is ResourceMeta object, but here I think s3 is Client object.

So you can just write

try: s3.download_file(bucket, key, localFilename) except Exception as e: ...

socrates
  • 1,203
  • 11
  • 16