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

somesingsomsing
  • 3,182
  • 4
  • 29
  • 46

1 Answers1

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
     }
Thales Minussi
  • 6,965
  • 1
  • 30
  • 48
  • 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 – somesingsomsing Mar 21 '19 at 22:11