boto3 error with logging handler

  • Last Update :
  • Techknowledgy :

I am getting this error when I try to import the boto3 library. I have installed boto3 1.4.1 and also tried downgrading to 1.3.1 and still I am getting this below error

Traceback (most recent call last):
File "storage.py", line 1, in <module>
   import boto3
   File "/Library/Python/2.7/site-packages/boto3/__init__.py", line 16, in <module>
      from boto3.session import Session
      File "/Library/Python/2.7/site-packages/boto3/session.py", line 17, in <module>
         import botocore.session
         File "/usr/local/lib/python2.7/site-packages/botocore/__init__.py", line 22, in <module>
            class NullHandler(logging.Handler):
            AttributeError: 'module' object has no attribute 'Handler'

Suggestion : 2

Boto3 classifies all AWS service errors and exceptions as ClientError exceptions. When attempting to catch AWS service exceptions, one way is to catch ClientError and then parse the error response for the AWS service-specific exception.,Catching exceptions through ClientError and parsing for error codes is still the best way to catch all service-side exceptions and errors.,Additional client-side issues with SSL negotiation, client misconfiguration, or AWS service validation errors will also throw botocore exceptions. Here’s a generic example of how you might catch botocore exceptions.,Using Amazon Kinesis as an example service, you can use Boto3 to catch the exception LimitExceededException and insert your own logging message when your code experiences request throttling from the AWS service.

import botocore.exceptions

for key, value in sorted(botocore.exceptions.__dict__.items()):
   if isinstance(value, type):
   print(key)
AliasConflictParameterError
ApiVersionNotFoundError
BaseEndpointResolverError
BotoCoreError
ChecksumError
ClientError
ConfigNotFound
ConfigParseError
ConnectTimeoutError
ConnectionClosedError
ConnectionError
CredentialRetrievalError
DataNotFoundError
EndpointConnectionError
EventStreamError
HTTPClientError
ImminentRemovalWarning
IncompleteReadError
InfiniteLoopConfigError
InvalidConfigError
InvalidDNSNameError
InvalidExpressionError
InvalidMaxRetryAttemptsError
InvalidRetryConfigurationError
InvalidS3AddressingStyleError
InvalidS3UsEast1RegionalEndpointConfigError
InvalidSTSRegionalEndpointsConfigError
MD5UnavailableError
MetadataRetrievalError
MissingParametersError
MissingServiceIdError
NoCredentialsError
NoRegionError
OperationNotPageableError
PaginationError
ParamValidationError
PartialCredentialsError
ProfileNotFound
ProxyConnectionError
RangeError
ReadTimeoutError
RefreshWithMFAUnsupportedError
SSLError
ServiceNotInRegionError
StubAssertionError
StubResponseError
UnStubbedResponseError
UndefinedModelAttributeError
UnknownClientMethodError
UnknownCredentialError
UnknownEndpointError
UnknownKeyError
UnknownParameterError
UnknownServiceError
UnknownServiceStyle
UnknownSignatureVersionError
UnseekableStreamError
UnsupportedS3AccesspointConfigurationError
UnsupportedS3ArnError
UnsupportedSignatureVersionError
UnsupportedTLSVersionWarning
ValidationError
WaiterConfigError
WaiterError
import botocore
import boto3

client = boto3.client('aws_service_name')

try:
client.some_api_call(SomeParam = 'some_param')

except botocore.exceptions.ClientError as error:
   # Put your error handling logic here
raise error

except botocore.exceptions.ParamValidationError as error:
   raise ValueError('The parameters you provided are incorrect: {}'.format(error))
{
   'Error': {
      'Code': 'SomeServiceException',
      'Message': 'Details/context around the exception or error'
   },
   'ResponseMetadata': {
      'RequestId': '1234567890ABCDEF',
      'HostId': 'host ID data will appear here as a hash',
      'HTTPStatusCode': 400,
      'HTTPHeaders': {
         'header metadata key/values will appear here'
      },
      'RetryAttempts': 0
   }
}
import botocore
import boto3
import logging

# Set up our logger
logging.basicConfig(level = logging.INFO)
logger = logging.getLogger()

client = boto3.client('kinesis')

try:
logger.info('Calling DescribeStream API on myDataStream')
client.describe_stream(StreamName = 'myDataStream')

except botocore.exceptions.ClientError as error:
   if error.response['Error']['Code'] == 'LimitExceededException':
   logger.warn('API call limit exceeded; backing off and retrying...')
else:
   raise error
except client.exceptions.LimitExceedException as error:
   logger.warn('API call limit exceeded; backing off and retrying...')

Suggestion : 3

This is useful when you're being passed in an exception but are outside the exception handler itself such as bubbling up the exception to a logging library for enrichment. Our final function looks like this:,We have to do more work handle errors based on their error code like these from the S3 docs. Your boto3 client also carries its own exception factory - you can build an exception class from any error code from those docs and catch it. ,We can handle being called as part of an except clause, or anywhere else we find a ClientError to match. This should help you write more readable code and handle errors when working with AWS APIs better.,Trek10 Team Support augments your team’s skills with access to a team of experienced and focused AWS solutions architects and cloud developers that specialize in leveraging AWS to the fullest.

Imagine you have a call that may fail (known more commonly as "every call"). It's a well-documented fact that saying "hah, no need to worry about X failing" is the only way to guarantee X will fail and page you at 3 am. You might write code like this using the S3 client to create a new bucket.

>>>
import boto3
   >>>
   s3 = boto3.client('s3') >>>
   s3.create_bucket(Bucket = 'test', ACL = 'private')
botocore.exceptions.ClientError: An error occurred(IllegalLocationConstraintException) when calling the CreateBucket operation: The unspecified location constraint is incompatible
for the region specific endpoint this request was sent to.

We have to do more work handle errors based on their error code like these from the S3 docs. Your boto3 client also carries its own exception factory - you can build an exception class from any error code from those docs and catch it.

import boto3
s3 = boto3.client('s3')
try:
s3.create_bucket(Bucket = 'test')
except s3.exceptions.from_code('IllegalLocationConstraintException'):
   print('bad location')

But this doesn't work how we think it does. If you try to catch two different error codes with this method we will always enter the first handler like this:

import boto3
s3 = boto3.client('s3')
try:
s3.create_bucket(Bucket = 'test')
except ddb.exceptions.from_code('SlowDown'):
   print('Calm yourself')
except ddb.exceptions.from_code('IllegalLocationConstraintException'):
   print('Bad location')

Now we've handled our error, but there may be a better way for us to deal with the wide variety of codes we might want to handle. One little-known fact about Python is the except clause is executed when the exception is being handled and doesn't just have to be an exception class. That's why we were able to write this line in an earlier example:

except ddb.exceptions.from_code('IllegalLocationConstraintException'):

The from_code function returns an exception class for Python to check and either catch or pass on. We can take advantage of this to examine the current exception. Then we can check the error code and if it's the one we're trying to match we return a ClientError that will trigger the clause to handle our exception. If we don't find a match, we'll return an exception subclass that doesn't exist (the NeverEverRaisedException) so that the clause will never be run.

import sys
import boto3
from botocore.exceptions
import ClientError

def is_client_error(code):
   e = sys.exc_info()[1]
if isinstance(e, ClientError) and e.response["Error"]["Code"] == code:
   return ClientError
return type("NeverEverRaisedException", (Exception, ), {})

s3 = boto3.client('s3')
try:
s3.create_bucket(Bucket = 'test')
except is_client_error('SlowDown'):
   print('Calm yourself')
except is_client_error('IllegalLocationConstraintException'):
   print('Bad location')

Suggestion : 4

Last updated: 2021-11-29

LIB_DIR = boto3 - mylayer / python
mkdir - p $LIB_DIR
pip3 install boto3 - t $LIB_DIR
cd boto3 - mylayer
zip - r / tmp / boto3 - mylayer.zip.
aws lambda publish - layer - version--layer - name boto3 - mylayer--zip - file fileb: ///tmp/boto3-mylayer.zip
arn: aws: lambda: region: $ACC_ID: layer: boto3 - mylayer: 1
aws lambda update-function-configuration --function-name myfunction --layers <layer ARN>