What you are printing is a python dict, it looks sort of like JSON but is not JSON, it is the representation of a python dict. That means it will have True / False instead of true / false, it will have ' instead of ", etc.

You could do print(json.dumps(event)) instead.

Anyway, the actual problem is that invokingEvent is yet another JSON, but in its string form, you need to to json.loads that nested JSON string. You can see that because the value after invokingEvent is inside another set of '...', therefore it is a string, not a parsed dict already.

invoking_event = json.loads(event['invokingEvent'])
change_type = invoking_event["configurationItemDiff"]["changeType"]

ruleParameters would be another nested JSON which needs parsing first if you wanted to use it.

Answer from luk2302 on Stack Overflow
🌐
Amazon Web Services
docs.aws.amazon.com › aws lambda › developer guide › aws lambda functions › programming languages › building lambda functions with python › define lambda function handler in python
Define Lambda function handler in Python - AWS Lambda
To see the event format for a particular service, refer to the appropriate page in the Invoking Lambda with events from other AWS services chapter. If the input event is in the form of a JSON object, the Lambda runtime converts the object to a Python dictionary.
Discussions

Malformed JSON in AWS Lambda using Python.
Probably Postman believes that the output is plain text. Try to set "Content-Type" header to "application/json". More on reddit.com
🌐 r/learnpython
2
1
September 11, 2023
Access json request from python in python AWS lambda function - Stack Overflow
I have an API in the AWS API gateway, connected to an AWS Lambda function in python, using lambda proxy integration. On my local computer, I am testing this API in python. I want to send a dictiona... More on stackoverflow.com
🌐 stackoverflow.com
How to retrieve well formatted JSON from AWS Lambda using Python - Stack Overflow
I have a function in AWS Lambda that connects to the Twitter API and returns the tweets which match a specific search query I provided via the event. A simplified version of the function is below. ... More on stackoverflow.com
🌐 stackoverflow.com
Python AWS Lambda Event JSON - Stack Overflow
I am trying to parse event data of AWS Lambda, I have connected it to SQS and I am sending the JSON format using SQS. This is my AWS Lambda Function import json def lambda_handler(event, context):... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Paepper
paepper.com › blog › posts › parsing-json-data-from-aws-lambda-functions-in-python
Parsing JSON data from AWS lambda functions in Python :: Read. Hack. Learn. Repeat. — This blog features state of the art applications in machine learning with a lot of PyTorch samples and deep learning code. You will learn about neural network optimization and potential insights for artificial intelligence for example in the medical domain.
March 31, 2020 - Let’s have a very pointless lambda function which takes the name of a user and returns it with some additional data back as JSON: def handler(event, context): user = event.get('user_name', None) if user is None: raise Exception('Please provide a user.') return { 'hello': 'world', 'user': user } Alright, easy enough. And here is how you would call it, pass the name and get the response back: import boto3 def get_from_lambda(): lambda_client = boto3.client('lambda') lambda_dict = {'user': 'hans_peter'} result = lambda_client.invoke( FunctionName='testfunction', InvocationType='RequestResponse', LogType='Tail', Payload=json.dumps(lambda_dict).encode('utf-8') ) return json.loads(result['Payload'].read().decode())
🌐
Reddit
reddit.com › r/learnpython › malformed json in aws lambda using python.
r/learnpython on Reddit: Malformed JSON in AWS Lambda using Python.
September 11, 2023 -

Hello LeanPython Sub-reddit!

I come to you because I have a problem formatting JSON in AWS Lambda.

I would like to tell you a little more, what happens is that I am developing an API in AWS Lambda, I created the database in PostgreSQL, and I am using Python to perform the queries, what happens is that I had a datatimes management error, because these values could not be formatted in a JSON, so I decided to make an encoder in a class which is responsible for carrying out this process of formatting it to JSON, but what happens is that it generates a JSON which is very poorly readable, in addition to being a headache when trying to manipulate it in the Frontend, below I will show you what I did and I would like to consult with you about a possible solution to this problem, please.

Below you will find the encoder class I was talking about:

class DateTimeEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, datetime):
            return o.isoformat()

        return json.JSONEncoder.default(self, o)

In the following function I am using json.dumps to format the output of the database query into JSON, in conjunction with the encoder:

def lambda_handler(event, context):
    cur = conn.cursor(cursor_factory=RealDictCursor)
    cur.execute("SELECT * FROM users")
    results = cur.fetchall()
    return  json.dumps(results, cls=DateTimeEncoder)

When deploying this in AWS in a Lambda, and when making the HTTP request through Postman, it generates the following poorly formatted output:

"[{\"id_usuario\": 2, \"cc\": \"123456789\", \"telefono\": \"987654321\", \"nombre\": \"John\", \"apellido\": \"Doe\", \"fecha_registro\": \"2023-07-03T02:34:38.452359\"}, {\"id_usuario\": 3, \"cc\": \"1013655876\", \"telefono\": \"2085686\", \"nombre\": \"Jane\", \"apellido\": \"Doe\", \"fecha_registro\": \"2023-07-03T20:08:42.603593\"}]"

What I want is for the above JSON to look like this:

[
  {
    "id_usuario": 2,
    "cc": "123456789",
    "telefono": "987654321",
    "nombre": "John",
    "apellido": "Doe",
    "fecha_registro": "2023-07-03T02:34:38.452359"
  },
  {
    "id_usuario": 3,
    "cc": "1013655876",
    "telefono": "2085686",
    "nombre": "Jane",
    "apellido": "Doe",
    "fecha_registro": "2023-07-03T20:08:42.603593"
  }
]

If you ask me, I have made other queries that have not had to use the json.dumps and it has generated the JSON with the correct format, however, when I implement the json.dumps in conjunction with the encoder, it generates that output which is difficult to read, I sincerely hope you can help me because I don't know what else to do.

🌐
DEV Community
dev.to › jenad88 › day-41-using-python-in-an-aws-lambda-function-3ckf
Day 41: Using Python in an AWS Lambda Function - DEV Community
May 27, 2023 - 1) First, create the 4 .json files mentioned above somewhere in a local folder. 2) In the AWS Console, navigate to AWS Lambda and Create a Function with a name of your choice. Make sure to select Python 3.10, 3.9 or 3.8 as the Runtime.
🌐
Medium
vinayakpandey-7997.medium.com › capturing-lambda-logs-in-json-format-d384f7c028c0
Capturing Lambda Logs In JSON Format - Vinayak Pandey - Medium
November 21, 2023 - Recently AWS announced native support for capturing Lambda logs in JSON format. So let’s see how that works. Step 1: Create a Python 3.10 Lambda function with following code:
Find elsewhere
🌐
Quora
quora.com › How-do-I-parse-JSON-data-from-AWS-Lambda-functions-in-Python
How to parse JSON data from AWS Lambda functions in Python - Quora
Answer: Firstly, AWS Lambda function is event driven. That mean, there is an event (like some one just put an object in S3), and this event source (i.e. S3) will trigger the Lambda function. So your Lambda function must be able to “handle” the event. Hence you write an event handler inside ...
🌐
Serverless Forums
forum.serverless.com › serverless framework
AWS Python Lambda Integration to Return JSON response directly - Serverless Framework - Serverless Forums
November 19, 2019 - This is a function on AWS with Lambda Proxy Integration. All default setting. The goal is to from the python lambda function, the HTTP response client gets is directly a JSON object, instead of a string serialization ...
🌐
FreeKB
freekb.net › Article
POST JSON to a Python Lambda Function using AWS ...
July 11, 2024 - This is super helpful when testing/debugging, but you probably wouldn't want to include print(event) after your testing/debugging is done, as this could add a bit of additional cost each time your Lambda Function is called. If you have print(event), then Cloudwatch > Log groups > /aws/lambda/myapi > yyyy/mm/dd/[$LATEST]abcdefg123456789abdefg123456789 should have something like this.
🌐
Amazon Web Services
docs.aws.amazon.com › aws lambda › developer guide › aws lambda functions › programming languages › building lambda functions with python › log and monitor python lambda functions
Log and monitor Python Lambda functions - AWS Lambda
XRAY TraceId – For traced requests, the AWS X-Ray trace ID. SegmentId – For traced requests, the X-Ray segment ID. Sampled – For traced requests, the sampling result. ... For supported Python runtimes, you can choose whether logs created using the standard logging module are captured in plain text or JSON. To learn more, see Using Lambda ...
🌐
Amazon Web Services
docs.aws.amazon.com › aws lambda › developer guide › aws lambda functions › programming languages › building lambda functions with python
Building Lambda functions with Python - AWS Lambda
These features must be enabled ... in Lambda, you can deploy your own Python runtime build with these features enabled, using a container image or custom runtime. In Python 3.12 and later Python runtimes, functions return Unicode characters as part of their JSON ...
Top answer
1 of 1
2
Your question and objective have multiple pieces: - Q: How to handle encoding decimal values to JSON. - A: Use a custom encoder like how you are doing - Documentation: https://stackoverflow.com/questions/1960516/python-json-serialize-a-decimal-object - Q: Avoiding reserved words - A: Use ProjectionExpression with ExpressionAttributeNames like how you are doing - Documentation: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html - Q: Simplest way to return a get response from DynamoDB using python - A: ``` import json import uuid import os import boto3 from datetime import datetime from decimal import Decimal class DecimalEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, Decimal): return str(obj) return json.JSONEncoder.default(self, obj) # Prepare DynamoDB client USERS_TABLE = os.getenv('USERS_TABLE', None) dynamodb = boto3.resource('dynamodb') ddbTable = dynamodb.Table(USERS_TABLE) def lambda_handler(event, context): route_key = f"{event['httpMethod']} {event['resource']}" # Set default response, override with data from DynamoDB if any response_body = {'Message': 'Unsupported route'} status_code = 400 headers = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' } try: # Get a list of all Users if route_key == 'GET /users': ddb_response = ddbTable.scan(Select='ALL_ATTRIBUTES') # return list of items instead of full DynamoDB response response_body = ddb_response['Items'] status_code = 200 # CRUD operations for a single User # Read a user by ID if route_key == 'GET /users/{userid}': # get data from the database ddb_response = ddbTable.get_item( Key={'userid': event['pathParameters']['userid']} ) # return single item instead of full DynamoDB response if 'Item' in ddb_response: response_body = ddb_response['Item'] else: response_body = {} status_code = 200 except Exception as err: status_code = 400 response_body = {'Error:': str(err)} print(str(err)) return { 'statusCode': status_code, 'body': json.dumps(response_body, cls=DecimalEncoder), 'headers': headers } ``` Your `mapped_items` object is just remapping the same values as exist in the items response, so if you don't need to rename those values in the json, you don't need that step. For example, this is the body of your response with and without the mapped_items: With mapped_items ``` [{\"col1\": \"1\", \"col2\": \"2\", \"col3\": \"3\", \"col4\": \"4\", \"col5\": \"5\", \"owner\": \"ddd\"}] ``` Without mapped_items (just returning response["Items"]) ``` [{\"col3\": \"3\", \"col4\": \"4\", \"col5\": \"5\", \"owner\": \"ddd\", \"col1\": \"1\", \"col2\": \"2\"}] ``` Also, it is better practice to establish the dynamoDB connection outside of the request handler (this is demonstrated in the above code). That way, if a warm invocation occurs, that invocation will use the existing dynamodDB connection and complete quicker References: https://catalog.workshops.aws/serverless-patterns/en-US
Top answer
1 of 2
6

So there are 3 problems:

Problem 1: In your example event, ['Records'][0]['Sns']['Message'] is a str in JSON format. That means that you need to parse to a dict like this:

 message = event['Records'][0]['Sns']['Message']
 message = json.loads(message)

Problem 2: message['Trigger']['Dimensions'] is a list but you are trying to access it like if it were a dict. So you only need to change your code to:

message = message['Trigger']['Dimensions'][0]['name']

Problem 3: Message is a str that means that you need to verify that is a plain str or json str (otherwise you are going to have problems with multiple structures and types). For that your code could look like:

 message = event['Records'][0]['Sns']['Message']
    if isinstance(message, str):
        try:
            message = json.loads(message)
        except Exception as e:
            print(e) # Or do nothing, this is just to log the error
    elif isinstance(message, list):
        message = message[0]
    # Maybe evaluate bool, tuple, etc other types

    print('RESPONSE', message['Trigger']['Dimensions'][0]['name'] if isinstance(message, dict) else message)

However I would also recommend to make it more extensible iterating the elements that you know are list. And for safety reasons (trying to avoid null pointer exceptions), use the get() function with a default value. http://www.tutorialspoint.com/python/dictionary_get.htm . Try maybe to create a function to parse structures and make it reusable.

Good luck!

2 of 2
1

Just as Records is a list, so you use ['Records'][0]['Sns']..., so is Dimensions, so again you need to access the first element.

🌐
Amazon Web Services
docs.aws.amazon.com › aws lambda › developer guide › aws lambda functions › create your first lambda function
Create your first Lambda function - AWS Lambda
To learn more about the Lambda ... in Python. ... The function lambda_handler takes two arguments, event and context. An event in Lambda is a JSON formatted document that contains data for your function to process. If your function is invoked by another AWS service, the ...