No message is showing up in lambda log in aws - amazon-web-services

I have an SQS queue that triggers a Lambda as soon as it gets a message. The lambda is getting triggered but I can't see any response when I use the receive_message API call.
import json
import urllib.parse
import boto3
sqs = boto3.client('sqs')
def lambda_handler(event, context):
try:
response = sqs.receive_message(
QueueUrl="https://sqs.us-east-1.amazonaws.com/*****/test-queue"
)
print("Response",response)
return
except Exception as e:
print(e)
raise e
Output
{'ResponseMetadata': {'RequestId': 'd4d364b9-ac8c-5dcd-a174-33b4aae995c9', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'd4d364b9-ac8c-5dcd-a174-33b4aae995c9', 'date': 'Sun, 12 Apr 2020 12:05:57 GMT', 'content-type': 'text/xml', 'content-length': '240'}, 'RetryAttempts': 0}}
Can someone help me here??

If you have your lambda function being automatically triggered by SQS, then the message(s) will be in the event object.
You don't have to call sqs.receive_message explicitly to read messages from the queue. Just use the event object.

Related

Why Records: [] is empty when i consume data from kinesis stream by python script?

I am trying to consume data from kinesis data stream which is created and produce data to it successfully , but when running consumer script in python :
import boto3
import json
from datetime import datetime
import time
my_stream_name = 'test'
kinesis_client = boto3.client('kinesis', region_name='us-east-1')
response = kinesis_client.describe_stream(StreamName=my_stream_name)
my_shard_id = response['StreamDescription']['Shards'][0]['ShardId']
shard_iterator = kinesis_client.get_shard_iterator(StreamName=my_stream_name,
ShardId=my_shard_id,
ShardIteratorType='LATEST')
my_shard_iterator = shard_iterator['ShardIterator']
record_response = kinesis_client.get_records(ShardIterator=my_shard_iterator,
Limit=2)
while 'NextShardIterator' in record_response:
record_response = kinesis_client.get_records(ShardIterator=record_response['NextShardIterator'],
Limit=2)
print(record_response)
# wait for 5 seconds
time.sleep(5)
But the output of the message data is empty ('Records': []):
{'Records': [], 'NextShardIterator':
'AAAAAAAAAAFFVFpvvveOquLUe7WO9nZAcYNQdcS6f6a+YGrrrjZo1gULcu/ZYxC7AB+xVlUhgL9UFPrQ22qmcQa6iIsmuKWl26buBk3utXlVqiGuDUYSgqMOtkp0Y7pJwa6N/I0fYfl2PLTXp5Qz8+5ZYuTW1KDt+PeSU3992bwgdOm7744cxcSnYFaQuHqfa0vLlaRBTOACVz4fwjggUBN01WdsoEjKmgtfNmuHSA7s9LLNzAapMg==',
'MillisBehindLatest': 0, 'ResponseMetadata': {'RequestId':
'e451dd27-c867-cf3d-be83-edbe95e9da9f', 'HTTPStatusCode': 200,
'HTTPHeaders': {'x-amzn-requestid':
'e451dd27-c867-cf3d-be83-edbe95e9da9f', 'x-amz-id-2':
'ClSlC3gRJuEqL9YJcHgC2N/TLSv56o+6406ki2+Zohnfo/erFVMDpPqkEWT+XAeeHXCdhYBbnOeZBPyesbXnVs45KQG78eRU',
'date': 'Thu, 14 Apr 2022 14:23:21 GMT', 'content-type':
'application/x-amz-json-1.1', 'content-length': '308'},
'RetryAttempts': 0}}

AWS Lambda: key error when sending a POST message

I have a very simple problem:
my lamda function works fine as long as i do not write something like "a = event["key"], but a = "test":
This is from Cloudwatch:
#message
[ERROR] KeyError: 'key1' Traceback (most recent call last):
#message
[ERROR] KeyError: 'key1' Traceback (most recent call last): File "/var/task/lambda_function.py", line 5, in lambda_handler a = event["key1]
This is what i have sent with postman (i even tried curl) in the body as raw data:
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
My lamda function looks like this:
import json
def lambda_handler(event, context):
# TODO implement
a = event["key1"]
return {
'statusCode': 200,
'body': json.dumps(a)
}
REST Api LAMBDA will pass the request as is where as LAMBDA_PROXY will append additonal metadata on query parms, api keys, etc. so, the input request body is passed as json string as attribute body. json.loads(event['body']) will give us the actual request body.
More details on changing integration type is here
Below code can extract key1 from input json object for Lambda_Proxy.
import json
def lambda_handler(event, context):
print(event)
a = json.loads(event['body'])['key1']
return {
'statusCode': 200,
'body': json.dumps(a)
}
Fastest way for me was to use a HTTP API and use form-data with key1=test. Then i printed event["body"] and found out that my body was base64 encoded. I used the following code to make that visible:
import json
import base64
def lambda_handler(event, context):
# TODO implement
a = event["body"]
print(a)
message_bytes = base64.b64decode(a)
message = message_bytes.decode('ascii')
return {
'statusCode': 200,
'body': json.dumps(message)
}
The output was:
"----------------------------852732202793625384403314\r\nContent-Disposition: form-data; name=\"key1\"\r\n\r\ntest\r\n----------------------------852732202793625384403314--\r\n"

Send Image over AWS SNS Notification with Boto3

I am trying to send an image stored in AWS Lambda /tmp/ folder.
I extract the image from AWS Kinesis Video Stream and write them to /tmp/ using opencv.
I am testing the code locally using boto3 but this would normally be in a lambda function.
import boto3
import base64
if __name__ == '__main__':
client = boto3.client('sns')
phone_number = '+12345678900'
img = open('tmp/image10.jpeg', 'rb').read()
response = client.publish(
PhoneNumber=phone_number,
Message = "here is a picture: ",
MessageAttributes = {
'store' : {"DataType": "Binary", "BinaryValue": base64.b64encode(img)}
}
)
print(response)
I am getting a success response and the text in Message argument but not the image:
{'MessageId': '2d435caa-bb24-5198-9bdc-04ecef05c0ef', 'ResponseMetadata': {'RequestId': '5t97d18b-p15f-554b-b93f-819df53e64bc', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '5c97d98b-a15f-554b-bf3f-819df53e64bc', 'content-type': 'text/xml', 'content-length': '294', 'date': 'Fri, 30 Oct 2020 17:49:20 GMT'}, 'RetryAttempts': 0}}

Error when sending message from lambda to DLQ

I am following this article in order to send from a lambda to a DLQ:
Using dead-letter queues in Amazon SQS — Boto3 documentation
The code is as follows
from datetime import datetime
import json
import os
import boto3
from botocore.vendored import requests
QUEUE_NAME = os.environ['QUEUE_NAME']
MAX_QUEUE_MESSAGES = os.environ['MAX_QUEUE_MESSAGES']
dead_letter_queue_arn = os.environ['DEAD_LETTER_QUEUE_ARN']
sqs = boto3.resource('sqs')
queue_url = os.environ['SQS_QUEUE_URL']
redrive_policy = {
'deadLetterTargetArn': dead_letter_queue_arn,
'maxReceiveCount': '10'
}
def lambda_handler(event, context):
# Receive messages from SQS queue
queue = sqs.get_queue_by_name(QueueName=QUEUE_NAME)
response = requests.post("http://httpbin.org/status/500", timeout=10)
if response.status_code == 500:
sqs.set_queue_attributes(QueueUrl=queue_url,
Attributes={
'RedrivePolicy': json.dumps(redrive_policy)
}
)
I am doing in this way because I need implement exponential backoff, but I cannot even send to DLQ becase this error
[ERROR] AttributeError: 'sqs.ServiceResource' object has no attribute 'set_queue_attributes'
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 24, in lambda_handler
    sqs.set_queue_attributes(QueueUrl=queue_url,
According to the set_queue_attributes() documentation, the object has the attribute set_queue_attributes.
Well in case anyone has the same problem, there is a difference between client and resource, I suppose the error has the necessary information but with AWS for me was difficult to spot, according to this
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.set_queue_attributes
response = client.set_queue_attributes(
QueueUrl='string',
Attributes={
'string': 'string'
}
)
You should be using the client
import boto3
client = boto3.client('sqs')
My mistake was I already has something from boto related to sqs
sqs = boto3.resource('sqs')
That is the reason the error
[ERROR] AttributeError: 'sqs.ServiceResource' object has no attribute 'set_queue_attributes'
because I need to use client instead resource from sqs

How to call an external API webservice from Python in Amazon Lambda?

I am pretty new to AWS Lambda i have a python code which has a post method for making an external API call,
import requests
import json
url = "http://sample/project"
headers = {
'content-type': "application/json"
}
r = request.post(url,headers=headers)
I tried putting it into a AWS Lamda call i tried like this below but it didn't get worked out
import requests
import json
url = "http://sample/project"
headers = {
'content-type': "application/json"
}
def lambda_handler(event, context):
response = requests.request("POST", url, headers=headers)
return response
But i am not getting in any response if i am running from local machine i am getting the output.Please help me how can i make a post call from AWS Lamda