Search code examples
amazon-web-servicesamazon-dynamodbaws-serverless

DynamoDB using the Serverless Python Template gives KeyError for body


The code for the lambda function is the following:

import json
import logging
import os
import time
import uuid

import boto3
dynamodb = boto3.resource('dynamodb')

def create(event, context):
    data = json.loads(event['body'])
    if 'text' not in data:
        logging.error("Validation Failed")
        raise Exception("Couldn't create the todo item.")
    
    timestamp = str(time.time())

    table = dynamodb.Table(os.environ['DYNAMODB_TABLE'])

    item = {
        'id': str(uuid.uuid1()),
        'name': data['text'],
        'description': data['text'],
        'price': data['text'],
        
        'createdAt': timestamp,
        'updatedAt': timestamp,
    }

    # write the todo to the database
    table.put_item(Item=item)

    # create a response
    response = {
        "statusCode": 200,
        "body": json.dumps(item)
    }

    return response

The test using AWS' Lambda's testing feature is:

{
  "name": "Masks",
  "description": "A box of 50 disposable masks",
  "price": "$10"
}

The log output is:

START RequestId: 5cf1c00a-dba5-4ef6-b5e7-b692d8235ffe Version: $LATEST
[ERROR] KeyError: 'body'
Traceback (most recent call last):
  File "/var/task/todos/create.py", line 12, in create
    data = json.loads(event['body'])END RequestId: 5cf1c00a-dba5-4ef6-b5e7-b692d8235ffe

Why is "body" giving me a key error? How do I fix this? The template is directly from www.severless.com, and based off of online tutorials, people have used the exact same code, albie with different values, successfully?

I've tried changing variable names and value to no avail.

sls deploy

Does successfully create the table, but I am unable to input any data into it. Edit 1: For those of you unfamiliar with AWS' Lambda Test feature, using Postman to input the same data is leading either to a 502 Gateway Error.


Solution

  • Assuming that this is the correct event object:

    {
      "name": "Masks",
      "description": "A box of 50 disposable masks",
      "price": "$10"
    }
    

    your code which matches this event should be:

    import json
    import logging
    import os
    import time
    import uuid
    
    import boto3
    
    dynamodb = boto3.resource('dynamodb')
    
    def create(event, context):
       
        timestamp = str(time.time())
    
        table = dynamodb.Table(os.environ['DYNAMODB_TABLE'])
    
        item = {
            'id': str(uuid.uuid1()),
            'name': event['name'],
            'description': event['description'],
            'price': event['price'],        
            'createdAt': timestamp,
            'updatedAt': timestamp,
        }
    
        # write the todo to the database
        table.put_item(Item=item)
    
        # create a response
        response = {
            "statusCode": 200,
            "body": json.dumps(item)
        }
    
        return response