I have a lambda with API gateway. So far I have tested it via "Test" tab in aws console and using below json file
{
"datasource": "XXX",
"action": "update",
"code": "test",
"time": "2023-03-20T11:39:50.0038136+00:00",
"data": {
"invoice": {
"invoiceId": "xxxx58d752f6f7f5d",
"type": "fixed",
"value": 5000
}
}
}
In my lambda
def lambda_handler(event, context):
s1 = json.dumps(event)
inv_event = json.loads(s1)
# Im reading values like below
invoiceId = inv_event['data']['invoice']['invoiceId']
This is working fine as expected. But now I am trying to hit this via api gateway and post the same json via postman and this started failing with error "[ERROR] TypeError: string indices must be integers". I have done a print of incoming event when call via postman and its like below
{'resource': '/hello', 'path': '/hello', 'httpMethod': 'POST', 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate, br', 'CloudFront-Forwarded-Proto': 'https', 'CloudFront-Is-Desktop-Viewer': 'true', 'CloudFront-Is-Mobile-Viewer': 'false', 'requestContext': {'resourceId': '3mm431', 'resourcePath': '/hello', 'httpMethod': 'POST', 'extendedRequestId': 'DoIXeECnIAMF8eg=', 'requestTime': '19/Apr/2023:13:34:01 +0000', 'path': '/Prod/hello', 'accountId': '597878062269', 'protocol': 'HTTP/1.1', 'stage': 'Prod', 'domainPrefix': 'xxxx', 'requestTimeEpoch': 1681911241190, 'requestId': 'ba1ee0c7-8b57-42bc-9335-d5548b1a084a', 'identity': {'cognitoIdentityPoolId': None, 'accountId': None, 'cognitoIdentityId': None, 'caller': None, 'sourceIp': '86.139.218.222', 'principalOrgId': None, 'accessKey': None, 'cognitoAuthenticationType': None, 'cognitoAuthenticationProvider': None, 'userArn': None, 'userAgent': 'PostmanRuntime/7.32.2', 'user': None}, 'domainName': 'xxxx.execute-api.xxxx.amazonaws.com', 'apiId': 'xxxx'}, 'body': '{\r\n \"datasource\": \"XXX\",\r\n \"action\": \"update\",\r\n \"code\": \"test\",\r\n \"time\": \"2023-03-20T11:39:50.0038136+00:00\",\r\n \"data\": {\r\n \"invoice\": {\r\n \"invoiceId\": \"xxxx58d752f6f7f5d\",\r\n \"type\": \"fixed\",\r\n \"value\": 5000\r\n }\r\n }\r\n }', 'isBase64Encoded': False}
Is there a way for me to extract the posted json and load it as json.loads?
You're just converting the entire event from a dict to a JSON string, and back to a dict with these two lines, they aren't actually accomplishing anything:
s1 = json.dumps(event)
inv_event = json.loads(s1)
The body
attribute of the event is a string representation of the request payload that was sent to API Gateway. You need to tell Python that that specific string is JSON, and needs to be parsed into a dict.
inv_event = json.loads(event['body'])
invoiceId = inv_event['data']['invoice']['invoiceId']