text: # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  # SPDX-License-Identifier: MIT-0
  
  # Implementation of the API backend for locations
  import json
  import uuid
  import os
  import boto3
  from datetime import datetime
  from aws_embedded_metrics import metric_scope
  
  # Patch libraries to instrument downstream calls
  # See https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-python-patching.html for more details
  from aws_xray_sdk.core import patch_all
  patch_all()
  
  # Prepare DynamoDB client
  LOCATIONS_TABLE = os.getenv('LOCATIONS_TABLE', None)
  dynamodb = boto3.resource('dynamodb')
  ddbTable = dynamodb.Table(LOCATIONS_TABLE)
  
  
  @metric_scope
  def lambda_handler(event, context, metrics):
      route_key = event['routeKey']
  
      # Set default response, override with data from DynamoDB if any
      response_body = {'Message': 'Unsupported route'}
      status_code = 400
      headers = {'Content-Type': 'application/json'}
  
      # Initialize putting common business metrics using EMF
      metric_payload = {}
      metrics.put_dimensions({'Service': 'Locations'})
      metrics.put_metric('ProcessedLocations', 1, 'Count')
      metrics.set_property('requestId', event['requestContext']['requestId'])
      metrics.set_property('routeKey', event['routeKey'])
  
      try:
          # Get all locations
          if route_key == 'GET /locations':
              # generate business metrics for the route
              metric_payload['operation'] = 'GET'
              ddb_response = ddbTable.scan(Select='ALL_ATTRIBUTES')
              # return list of items instead of full DynamoDB response
              response_body = ddb_response['Items']
              status_code = 200
          # Location CRUD operations
          if route_key == 'GET /locations/{locationid}':
              # generate business metrics for the route
              metric_payload['operation'] = 'GET'
              metric_payload['locationid'] = event['pathParameters']['locationid']
              # get data from the database
              ddb_response = ddbTable.get_item(
                  Key={'locationid': event['pathParameters']['locationid']}
              )
              # return list of items instead of full DynamoDB response
              if 'Item' in ddb_response:
                  response_body = ddb_response['Item']
              else:
                  response_body = {}
              status_code = 200
          if route_key == 'DELETE /locations/{locationid}':
              # generate business metrics for the route
              metric_payload['operation'] = 'DELETE'
              metric_payload['locationid'] = event['pathParameters']['locationid']
              # delete item in the database
              ddbTable.delete_item(
                  Key={'locationid': event['pathParameters']['locationid']}
              )
              response_body = {}
              status_code = 200
          if route_key == 'PUT /locations':
              request_json = json.loads(event['body'])
              request_json['timestamp'] = datetime.now().isoformat()
              # generate unique id if it isn't present in the request
              if 'locationid' not in request_json:
                  request_json['locationid'] = str(uuid.uuid1())
              # generate business metrics for the route
              metric_payload['operation'] = 'PUT'
              metric_payload['locationid'] = request_json['locationid']
              # update the database
              ddbTable.put_item(
                  Item=request_json
              )
              response_body = request_json
              status_code = 200
      except Exception as err:
          status_code = 400
          response_body = {'Error:': str(err)}
          print(str(err))
      # Add route specific business metrics
      metrics.set_property("Payload", metric_payload)
      return {
          'statusCode': status_code,
          'body': json.dumps(response_body),
          'headers': headers
      }
  