2

I have created a simple python 3.7 lambda function:

import json
import boto3

s3 = boto3.client("s3")


def lambda_handler(event, context):
    bucket = "nubi-data"
    key = "core/user.json"

    try:
        data = s3.get_object(Bucket=bucket, Key=key)
        json_data = data['Body'].read()

        #return json_data

        return {
            'statusCode': 200,
            "headers": {"Content-Type": "application/json"},
            'body': json.loads(json_data)
            }


    except Exception as e:
        print(e)
        raise e

This function reads a json file from an s3 bucket. The json file looks like:

{ "id": 1, "name": "John", "pwd": "password" }

The function runs successfully when I test from within function editor screen in AWS console with the following output: enter image description here

Response: { "statusCode": 200, "headers": { "Content-Type": "application/json" }, "body": { "id": 1, "name": "John", "pwd": "password" } }

Request ID: "f57de02f-44dd-4854-9df9-9f3a8c90031d"

Function Logs: START RequestId: f57de02f-44dd-4854-9df9-9f3a8c90031d Version: $LATEST END RequestId: f57de02f-44dd-4854-9df9-9f3a8c90031d REPORT RequestId: f57de02f-44dd-4854-9df9-9f3a8c90031d Duration: 260.70 ms Billed Duration: 300 ms Memory Size: 128 MB Max Memory Used: 84 MB

But when I test the function from the API Gateway, I get the error
enter image description here

Thu Mar 21 21:04:08 UTC 2019 : Endpoint response body before transformations: {"statusCode": 200, "headers": {"Content-Type": "application/json"}, "body": {"id": 1, "name": "John", "pwd": "password"}} Thu Mar 21 21:04:08 UTC 2019 : Execution failed due to configuration error: Malformed Lambda proxy response Thu Mar 21 21:04:08 UTC 2019 : Method completed with status: 502

1 Answer 1

2

Change

'body': json.loads(json_data)

to

'body': json.dumps(json_data)

API Gateway expects a String as output and json.dumps does exactly this. json.loads, on the other hand, creates a JSON out of a String. If you know NodeJS, they're equivalent to JSON.stringify and JSON.parse, respectively.

Example

json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])

produces

'["foo", {"bar": ["baz", null, 1.0, 2]}]'

while

json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')

produces

[u'foo', {u'bar': [u'baz', None, 1.0, 2]}]

This information is available in the official docs

EDIT

One more thing both the OP and I missed is that data['Body'].read() doesn't return the JSON itself but a buffer instead. It needs to be decoded first.

json_data = data['Body'].read().decode('utf-8') will return the stringified JSON already (just because your file is a JSON, of course), so on your return statement you should be able to simply do it like this:

return {
         'statusCode': 200,
         "headers": {"Content-Type": "application/json"},
         'body': json_data
     }
Sign up to request clarification or add additional context in comments.

1 Comment

I tried that as well. Here is the error I get when using dumps: Thu Mar 21 22:10:53 UTC 2019 : Lambda execution failed with status 200 due to customer function error: Object of type bytes is not JSON serializable. Lambda request id: a3c6d525-d4c4-4bd0-a7fc-901a8bab8111 Thu Mar 21 22:10:53 UTC 2019 : Method completed with status: 502

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.