Lambda Function working, but cannot work with API Gateway - amazon-web-services

I have a working Lambda function when I test it using a test event:
{
"num1_in": 51.5,
"num2_in": -0.097
}
import json
import Function_and_Data_List
#Parse out query string parameters
def lambda_handler(event, context):
num1_in = event['num1_in']
num2_in = event['num2_in']
coord = {'num1': num1_in, 'num2': num2_in}
output = func1(Function_and_Data_List.listdata, coord)
return {
"Output": output
}
However, when I use API gateway to create a REST API I keep getting errors. My method for the REST API are:
1.) Build REST API
2.) Actions -> Create Resource
3.) Actions -> Create Method -> GET
4.) Integration type is Lambda Function, Use Lambda Proxy Integration
5.) Deploy
What am I missing for getting this API to work?

If you use lambda proxy integration, your playload will be in the body. You seem also having incorrect return format.
Therefore, I would recommend trying out the following version of your code:
import json
import Function_and_Data_List
#Parse out query string parameters
def lambda_handler(event, context):
print(event)
body = json.loads(event['body'])
num1_in = body['num1_in']
num2_in = body['num2_in']
coord = {'num1': num1_in, 'num2': num2_in}
output = func1(Function_and_Data_List.listdata, coord)
return {
"statusCode": 200,
"body": json.dumps(output)
}
In the above I also added print(event) so that in the CloudWatch Logs you can inspect the event object which should help debug the issue.

Related

CDK CustomResource attribute error: Vendor response doesn't contain key in object

Using CDK, I have an aws custom resource that I want to get a value from its response. Unfortunately, I've been getting the error in the title. A simplified version of the response of the lambda that is invoked by the resource is found below:
public class Response {
private ResponseInfo info;
}
The lambda handler using this response is here
I have tested in AWS Lambda console that the lambda indeed returns json of the form:
{
"info": {...}
}
but when I try to get it (from my custom resource that triggered the lambda) with:
flyway_resource.get_response_field("info")
I get the error in the title. Any I ideas? How can I view what the custom resource's response actually looks like so that I can use the right keys?
You can view the custom resource definition here
The return json object from your custom resource doesn't have the field "info". I would use boto3 to create the resource and print the response in the console to see how it looks like:
Something like this:
client = boto3.client('Lambda', region_name='ap-southeast-2')
response = client.invoke(
FunctionName='string',
InvocationType='Event'|'RequestResponse'|'DryRun',
LogType='None'|'Tail',
ClientContext='string',
Payload=b'bytes'|file,
Qualifier='string'
)
print(response)
the response of your custom resource seems to be something like this:
{
'StatusCode': 123,
'FunctionError': 'string',
'LogResult': 'string',
'Payload': StreamingBody(),
'ExecutedVersion': 'string'
}
but you can verify it with the boto3 call
boto3 documentation: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/lambda.html?highlight=lambda#Lambda.Client.invoke

Can we Integrate AWS lambda with AWS IOT and perform operations in the IOT using this lambda function?

The scenario is like this
I have a microservice which invokes a LAMBDA function whose role will be to delete things from the AWS IOT.
Is there a way I can perform operations in AWS IOT using the lambda function?
Any article, blog regarding this will be a huge help as I'm not able to find any integration document on the web.
I found a way to do several operations in AWS IOT using lambda function by the means of API's.
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iot.html#IoT.Client.delete_thing_group
The above link has description about API's which will help in this case.
A sample lambda function script to delete a thing from the IOT is
import json
import boto3
def lambda_handler(event, context):
thing_name = event['thing_name']
delete_thing(thing_name=thing_name)
def delete_thing(thing_name):
c_iot = boto3.client('iot')
print(" DELETING {}".format(thing_name))
try:
r_principals = c_iot.list_thing_principals(thingName=thing_name)
except Exception as e:
print("ERROR listing thing principals: {}".format(e))
r_principals = {'principals': []}
print("r_principals: {}".format(r_principals))
for arn in r_principals['principals']:
cert_id = arn.split('/')[1]
print(" arn: {} cert_id: {}".format(arn, cert_id))
r_detach_thing = c_iot.detach_thing_principal(thingName=thing_name, principal=arn)
print("DETACH THING: {}".format(r_detach_thing))
r_upd_cert = c_iot.update_certificate(certificateId=cert_id, newStatus='INACTIVE')
print("INACTIVE: {}".format(r_upd_cert))
r_del_cert = c_iot.delete_certificate(certificateId=cert_id, forceDelete=True)
print(" DEL CERT: {}".format(r_del_cert))
r_del_thing = c_iot.delete_thing(thingName=thing_name)
print(" DELETE THING: {}\n".format(r_del_thing))
And the input for this lambda function will be
{
"thing_name": "MyIotThing"
}

create request body and template API GATEWAY CDK

Please tell me two things:
1. How to configure request body via sdk
2. how to configure template, for pulling pass or query param, converting to json, and then passing it to lambda
This is all in the api gateway and via cdk
Assume you have the following setup
const restapi = new apigateway.RestApi(this, "myapi", {
// detail omit
});
const helloWorld = new lambda.Function(this, "hello", {
runtime: lambda.Runtime..PYTHON_3_8,
handler: 'index.handler',
code: Code.asset('./index.py')
})
restapi.root.addResource("test").addMethod("POST", new apigateway.LambdaIntegration(helloWorld))
and inside the lambda function (in python)
def handler(event, context):
request_body = event['body']
parameters = event[queryStringParameters]

How to link two lambda functions from API gateway

I have two lambda functions
Lambda 1:
def save_events(event):
result = []
conn = pymysql.connect(rds_host, user=name, passwd=password,
db=db_name,connect_timeout=30)
with conn.cursor() as cur:
cur.execute("SELECT * FROM bodyparts")
for row in cur:
result.append(list(row))
cur.close()
bodyparts = json.dumps(result)
bodyParts=(bodyparts.replace("\"", "'"))
def lambda_handler(event, context):
save_events(event)
return bodyParts
Lambda 2:
def save_events(event):
result = []
conn = pymysql.connect(rds_host, user=, passwd=, db=, connect_timeout=30)
with conn.cursor(pymysql.cursors.DictCursor) as cur:
cur.execute("select exid,exercise_name,image from exercise where bid = 3")
result = cur.fetchall()
cur.close()
print ("Data from RDS...")
print (result)
workout = json.dumps(result)
workouts=(workout.replace("\"", "'"))
def lambda_handler(event, context):
save_events(event)
return workouts
After the successful execution of lambda 1 it will return list as a json object to the browser using API gateway and now how to invoke the lambda 2 function in API gateway based on the user selection from the output of lambda1 function.
In lambda2 how to pass user selected item as "bid" value in query.
I know the theory part, really stuck with the implementation part as am a beginner to backend development, Any help would be much appreciated
I think that a good option for you is AWS Step Function. If you use Step Functions you can have 2 states with a lambda in each state, the state 1 execute your lambda 1 and pass the result to the second state and execute in it lambda 2. Remember that Step Functions can be called from API Gateway so if you are using API Gateway like endpoint you only need to change the target to Step Functions instead the lambda function. A good way to create all this resources is SAM (Serverless Application Model), using swagger.

AWS Lambda Function assistance

I just started with AWS and i am creating my first Lambda functions. The first one was success - no issues when creating and executing.
Now i am trying to create Lambda function (python 3 based) with couple parameters. When i perform test from the API Gateway i can see it executes ok. When i try to execute from browser i see the following error:
{
"errorMessage": "'foo2",
"errorType": "KeyError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 6, in lambda_handler\n foo2 = event['foo2'];\n"
]
}
Here is the function and mapping templates:
import json
import sys
def lambda_handler(event, context):
foo1 = event['foo1'];
foo2 = event['foo2'];
foo3 = event['foo3'];
foo = "This is Test!";
# TODO implement
return {
'statusCode': 200,
'body': json.dumps(event)
}
Mapping template
#set($inputRoot = $input.path('$'))
{
"foo1": "$input.params('foo1')",
"foo2": "$input.params('foo2')",
"foo3": "$input.params('foo3')"
}
I really wonder why this is happening..
I'm not an API gateway wizard, but it looks like you are trying to assign the variable foo2 to a part of the event that doesn't exist when invoking the function from the Browser, when testing the event you might want to look at the structure of the event. It might help inside your Lambda function to add a json.dumps direct under the lambda_handler to try understand if there are missing parameters.