在 IoT Analytics 中触发的 Lambda 函数将 POST 请求发送到外部 API
Lambda function trigerred in IoT Analytics which sends POST requests to an external API
我正在尝试在 Python 中设置一个 AWS Lambda 函数,该函数在 IOT Analytics 处理期间触发并向外部 API 发送两个连续的 POST 请求(如果条件满足)。我无法直接导入 "request" 包,因为它对于内联编辑来说太大了,所以我已经将我的 Python 脚本和包上传到 zip 文件中,然后将其上传到 AWS。
当 运行 lambda 时,我在请求包文件上遇到错误,我不太明白。我也不确定如何 return API 响应,因为我的响应出现序列化错误。这是我的 lambda 代码:
import json
import os
import time
import requests
def lambda_handler(event,context):
headers = {
"authorization": "Basic XXXXXXXXX",
"content_type": "application/json"
} #API request header
url = "https://example.com/path" #API request URL
msgs = json.loads(json.dumps(event))
for msg in msgs:
deviceID = msg["deviceID"]
data = msg["data"]
if (condition over received message):
body1 = {
"paramAA": paramAA,
"paramB": [{
"paramBA": paramBA1,
"paramBB": paramBB
}]
}
response_1 = requests.post(url,headers=headers,data=body1) #First API request
time.sleep(600)
body2 = {
"paramAA": paramAA,
"paramB": [{
"paramBA": paramBA2,
"paramBB": paramBB,
}]
}
response_2 = requests.post(url,headers=headers,data=body2) #Second API request
else:
pass
else:
pass
return {
'statusCode': 200,
'url' : url,
'response_1.code' : response_1.status_code,
'response_1_msg' : response_1.text,
'response_2.code' : response_2.status_code,
'response_2_msg' : response_2.text
}
您知道如何解决这些错误吗?
如果我将 return 更改为 "reponse_1 : json.dumps(response1)",我会收到这些错误(无论是压缩包还是 SDK):
{
"errorMessage": "Object of type Response is not JSON serializable",
"errorType": "TypeError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 56, in lambda_handler\n 'response_1' : json.dumps(response_1),\n",
" File \"/var/lang/lib/python3.8/json/__init__.py\", line 231, in dumps\n return _default_encoder.encode(obj)\n",
" File \"/var/lang/lib/python3.8/json/encoder.py\", line 199, in encode\n chunks = self.iterencode(o, _one_shot=True)\n",
" File \"/var/lang/lib/python3.8/json/encoder.py\", line 257, in iterencode\n return _iterencode(o, 0)\n",
" File \"/var/lang/lib/python3.8/json/encoder.py\", line 179, in default\n raise TypeError(f'Object of type {o.__class__.__name__} '\n"
看来 json 库只能将标准类型转换为字符串,但我不得不对更复杂的对象使用 pickle。我已经相应地修改了我的代码,并以 utf-8 编码错误结束:
"errorMessage": "Unable to marshal response: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte"
这是我现在的脚本:
import pickle
import os
import time
import requests
def lambda_handler(event,context):
headers = {
"authorization": "Basic XXXXXXXXX",
"content_type": "application/json"
} #API request header
url = "https://example.com/path" #API request URL
msgs = pickle.loads(pickle.dumps(event))
for msg in msgs:
deviceID = msg["deviceID"]
data = msg["data"]
if (condition over received message):
body1 = {
"paramAA": paramAA,
"paramB": [{
"paramBA": paramBA1,
"paramBB": paramBB
}]
}
response_1 = requests.post(url,headers=headers,data=pickle.dumps(body1)) #First API request
exec_verif = "request 1 sent"
time.sleep(600)
body2 = {
"paramAA": paramAA,
"paramB": [{
"paramBA": paramBA2,
"paramBB": paramBB,
}]
}
response_2 = requests.post(url,headers=headers,data=pickle.dumps(body2)) #Second API request
exec_verif = "request 2 sent"
else:
response_1 = "fail1"
response_2 = "fail1"
else:
response_1 = "fail2"
response_2 = "fail2"
return {
'statusCode': 200,
'exec_verif' : exec_verif,
'response_1' : pickle.dumps(response_1),
'response_2' : pickle.dumps(response_2)
}
令我感到奇怪的是,如果我不在 return 中包含 response_1 和 response_2,该函数将执行并发回 200 状态,其中 'exec_verif' 是 "request 2 sent",而没有实际调用外部 API。在 API 日志中没有任何呼叫的痕迹,甚至是不成功的呼叫。
使用 base64 编码对我有用。
这里给出了一个例子;
https://docs.aws.amazon.com/apigateway/latest/developerguide/lambda-proxy-binary-media.html
我正在尝试在 Python 中设置一个 AWS Lambda 函数,该函数在 IOT Analytics 处理期间触发并向外部 API 发送两个连续的 POST 请求(如果条件满足)。我无法直接导入 "request" 包,因为它对于内联编辑来说太大了,所以我已经将我的 Python 脚本和包上传到 zip 文件中,然后将其上传到 AWS。
当 运行 lambda 时,我在请求包文件上遇到错误,我不太明白。我也不确定如何 return API 响应,因为我的响应出现序列化错误。这是我的 lambda 代码:
import json
import os
import time
import requests
def lambda_handler(event,context):
headers = {
"authorization": "Basic XXXXXXXXX",
"content_type": "application/json"
} #API request header
url = "https://example.com/path" #API request URL
msgs = json.loads(json.dumps(event))
for msg in msgs:
deviceID = msg["deviceID"]
data = msg["data"]
if (condition over received message):
body1 = {
"paramAA": paramAA,
"paramB": [{
"paramBA": paramBA1,
"paramBB": paramBB
}]
}
response_1 = requests.post(url,headers=headers,data=body1) #First API request
time.sleep(600)
body2 = {
"paramAA": paramAA,
"paramB": [{
"paramBA": paramBA2,
"paramBB": paramBB,
}]
}
response_2 = requests.post(url,headers=headers,data=body2) #Second API request
else:
pass
else:
pass
return {
'statusCode': 200,
'url' : url,
'response_1.code' : response_1.status_code,
'response_1_msg' : response_1.text,
'response_2.code' : response_2.status_code,
'response_2_msg' : response_2.text
}
您知道如何解决这些错误吗?
如果我将 return 更改为 "reponse_1 : json.dumps(response1)",我会收到这些错误(无论是压缩包还是 SDK):
{
"errorMessage": "Object of type Response is not JSON serializable",
"errorType": "TypeError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 56, in lambda_handler\n 'response_1' : json.dumps(response_1),\n",
" File \"/var/lang/lib/python3.8/json/__init__.py\", line 231, in dumps\n return _default_encoder.encode(obj)\n",
" File \"/var/lang/lib/python3.8/json/encoder.py\", line 199, in encode\n chunks = self.iterencode(o, _one_shot=True)\n",
" File \"/var/lang/lib/python3.8/json/encoder.py\", line 257, in iterencode\n return _iterencode(o, 0)\n",
" File \"/var/lang/lib/python3.8/json/encoder.py\", line 179, in default\n raise TypeError(f'Object of type {o.__class__.__name__} '\n"
看来 json 库只能将标准类型转换为字符串,但我不得不对更复杂的对象使用 pickle。我已经相应地修改了我的代码,并以 utf-8 编码错误结束:
"errorMessage": "Unable to marshal response: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte"
这是我现在的脚本:
import pickle
import os
import time
import requests
def lambda_handler(event,context):
headers = {
"authorization": "Basic XXXXXXXXX",
"content_type": "application/json"
} #API request header
url = "https://example.com/path" #API request URL
msgs = pickle.loads(pickle.dumps(event))
for msg in msgs:
deviceID = msg["deviceID"]
data = msg["data"]
if (condition over received message):
body1 = {
"paramAA": paramAA,
"paramB": [{
"paramBA": paramBA1,
"paramBB": paramBB
}]
}
response_1 = requests.post(url,headers=headers,data=pickle.dumps(body1)) #First API request
exec_verif = "request 1 sent"
time.sleep(600)
body2 = {
"paramAA": paramAA,
"paramB": [{
"paramBA": paramBA2,
"paramBB": paramBB,
}]
}
response_2 = requests.post(url,headers=headers,data=pickle.dumps(body2)) #Second API request
exec_verif = "request 2 sent"
else:
response_1 = "fail1"
response_2 = "fail1"
else:
response_1 = "fail2"
response_2 = "fail2"
return {
'statusCode': 200,
'exec_verif' : exec_verif,
'response_1' : pickle.dumps(response_1),
'response_2' : pickle.dumps(response_2)
}
令我感到奇怪的是,如果我不在 return 中包含 response_1 和 response_2,该函数将执行并发回 200 状态,其中 'exec_verif' 是 "request 2 sent",而没有实际调用外部 API。在 API 日志中没有任何呼叫的痕迹,甚至是不成功的呼叫。
使用 base64 编码对我有用。 这里给出了一个例子; https://docs.aws.amazon.com/apigateway/latest/developerguide/lambda-proxy-binary-media.html