# Buggy code
def send_notifications(method, bucket_name, object_path):
    for bucket, config in iteritems(S3_NOTIFICATIONS):
        if bucket == bucket_name:
            action = {"PUT": "ObjectCreated", "DELETE": "ObjectRemoved"}[method]
            # TODO: support more detailed methods, e.g., DeleteMarkerCreated
            # http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html
            api_method = {"PUT": "Put", "DELETE": "Delete"}[method]
            event_name = "%s:%s" % (action, api_method)
            if event_type_matches(
                config["Event"], action, api_method
            ) and filter_rules_match(config.get("Filter"), object_path):
                # send notification
                message = get_event_message(
                    event_name=event_name,
                    bucket_name=bucket_name,
                    file_name=urlparse.urlparse(object_path[1:]).path,
                )
                message = json.dumps(message)
                if config.get("Queue"):
                    sqs_client = aws_stack.connect_to_service("sqs")
                    try:
                        queue_url = queue_url_for_arn(config["Queue"])
                        sqs_client.send_message(QueueUrl=queue_url, MessageBody=message)
                    except Exception as e:
                        LOGGER.warning(
                            'Unable to send notification for S3 bucket "%s" to SQS queue "%s": %s'
                            % (bucket_name, config["Queue"], e)
                        )
                if config.get("Topic"):
                    sns_client = aws_stack.connect_to_service("sns")
                    try:
                        sns_client.publish(TopicArn=config["Topic"], Message=message)
                    except Exception as e:
                        LOGGER.warning(
                            'Unable to send notification for S3 bucket "%s" to SNS topic "%s".'
                            % (bucket_name, config["Topic"])
                        )
                if config.get("CloudFunction"):
                    # make sure we don't run into a socket timeout
                    config = botocore.config.Config(read_timeout=300)
                    lambda_client = aws_stack.connect_to_service(
                        "lambda", config=config
                    )
                    try:
                        lambda_client.invoke(
                            FunctionName=config["CloudFunction"], Payload=message
                        )
                    except Exception as e:
                        LOGGER.warning(
                            'Unable to send notification for S3 bucket "%s" to Lambda function "%s".'
                            % (bucket_name, config["CloudFunction"])
                        )
                if not filter(
                    lambda x: config.get(x), ("Queue", "Topic", "CloudFunction")
                ):
                    LOGGER.warning(
                        "Neither of Queue/Topic/CloudFunction defined for S3 notification."
                    )


# Traceback (TypeError)
2017-11-15T01:23:19:ERROR:localstack.services.generic_proxy: Error forwarding request: 'Config' object has no attribute '__getitem__' Traceback (most recent call last):
File "/opt/code/localstack/localstack/services/generic_proxy.py", line 196, in forward
updated_response = self.proxy.update_listener.return_response(**kwargs)
File "/opt/code/localstack/localstack/services/s3/s3_listener.py", line 493, in return_response
send_notifications(method, bucket_name, object_path)
File "/opt/code/localstack/localstack/services/s3/s3_listener.py", line 160, in send_notifications
(bucket_name, config['CloudFunction']))
TypeError: 'Config' object has no attribute '__getitem__'

# Fixed code
def send_notifications(method, bucket_name, object_path):
    for bucket, config in iteritems(S3_NOTIFICATIONS):
        if bucket == bucket_name:
            action = {"PUT": "ObjectCreated", "DELETE": "ObjectRemoved"}[method]
            # TODO: support more detailed methods, e.g., DeleteMarkerCreated
            # http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html
            api_method = {"PUT": "Put", "DELETE": "Delete"}[method]
            event_name = "%s:%s" % (action, api_method)
            if event_type_matches(
                config["Event"], action, api_method
            ) and filter_rules_match(config.get("Filter"), object_path):
                # send notification
                message = get_event_message(
                    event_name=event_name,
                    bucket_name=bucket_name,
                    file_name=urlparse.urlparse(object_path[1:]).path,
                )
                message = json.dumps(message)
                if config.get("Queue"):
                    sqs_client = aws_stack.connect_to_service("sqs")
                    try:
                        queue_url = queue_url_for_arn(config["Queue"])
                        sqs_client.send_message(QueueUrl=queue_url, MessageBody=message)
                    except Exception as e:
                        LOGGER.warning(
                            'Unable to send notification for S3 bucket "%s" to SQS queue "%s": %s'
                            % (bucket_name, config["Queue"], e)
                        )
                if config.get("Topic"):
                    sns_client = aws_stack.connect_to_service("sns")
                    try:
                        sns_client.publish(TopicArn=config["Topic"], Message=message)
                    except Exception as e:
                        LOGGER.warning(
                            'Unable to send notification for S3 bucket "%s" to SNS topic "%s".'
                            % (bucket_name, config["Topic"])
                        )
                if config.get("CloudFunction"):
                    # make sure we don't run into a socket timeout
                    connection_config = botocore.config.Config(read_timeout=300)
                    lambda_client = aws_stack.connect_to_service(
                        "lambda", config=connection_config
                    )
                    try:
                        lambda_client.invoke(
                            FunctionName=config["CloudFunction"], Payload=message
                        )
                    except Exception as e:
                        LOGGER.warning(
                            'Unable to send notification for S3 bucket "%s" to Lambda function "%s".'
                            % (bucket_name, config["CloudFunction"])
                        )
                if not filter(
                    lambda x: config.get(x), ("Queue", "Topic", "CloudFunction")
                ):
                    LOGGER.warning(
                        "Neither of Queue/Topic/CloudFunction defined for S3 notification."
                    )