text: import os
  import json
  import cfnresponse
  
  import boto3
  from botocore.exceptions import ClientError
  
  client = boto3.client('s3')
  
  import logging
  
  logger = logging.getLogger()
  logger.setLevel(logging.INFO)
  
  
  def handler(event, context):
      logger.info("Received event: %s" % json.dumps(event))
      source_bucket = event['ResourceProperties'].get('SourceBucket') or None
      source_prefix = event['ResourceProperties'].get('SourcePrefix') or ''
      bucket = event['ResourceProperties'].get('Bucket') or None
      prefix = event['ResourceProperties'].get('Prefix') or ''
      request_type = event.get('RequestType') or None
  
      result = cfnresponse.SUCCESS
  
      if request_type == None:
          cfnresponse.send(event, context, result, {})
  
      try:
          if request_type == 'Create' or request_type == 'Update':
              result = copy_objects(source_bucket, source_prefix, bucket, prefix)
          elif request_type == 'Delete':
              result = delete_objects(bucket, prefix)
      except ClientError as e:
          logger.error('Error: %s', e)
          result = cfnresponse.FAILED
  
  
      cfnresponse.send(event, context, result, {})
  
  
  def copy_objects(source_bucket, source_prefix, bucket, prefix):
      if source_bucket == None or bucket == None:
          return cfnresponse.SUCCESS
  
      paginator = client.get_paginator('list_objects_v2')
      page_iterator = paginator.paginate(Bucket=source_bucket, Prefix=source_prefix)
      try:
          for key in {x['Key'] for page in page_iterator for x in page['Contents']}:
              source_key = key
              dest_key = os.path.join(prefix, os.path.relpath(key, source_prefix))
              print 'copy {} to {}'.format(key, dest_key)
              client.copy_object(CopySource={'Bucket': source_bucket, 'Key': key}, Bucket=bucket, Key=dest_key)
      except KeyError as e:
          logger.error('Error: %s', e)
  
      return cfnresponse.SUCCESS
  
  
  def delete_objects(bucket, prefix):
      if bucket == None:
          return cfnresponse.SUCCESS
  
      versioning = client.get_bucket_versioning(Bucket=bucket)
      versioning_status = versioning.get('Status') or 'Disabled'
      if versioning_status == 'Enabled':
          paginator = client.get_paginator('list_object_versions')
          page_iterator = paginator.paginate(Bucket=bucket, Prefix=prefix)
          try: objects = [{'Key': x['Key'],'VersionId': x['VersionId']} for page in page_iterator for x in page['Versions']]
          except KeyError: objects = None
  
      else:
          paginator = client.get_paginator('list_objects_v2')
          page_iterator = paginator.paginate(Bucket=bucket, Prefix=prefix)
          try: objects = [{'Key': x['Key']} for page in page_iterator for x in page['Contents']]
          except KeyError: objects = None
  
      if objects != None:
          client.delete_objects(Bucket=bucket, Delete={'Objects': objects})
  
      return cfnresponse.SUCCESS
  