Лямбда-функция, запускаемая в IoT Analytics, которая отправляет запросы POST во внешний API.
Я пытаюсь установить функцию AWS Lambda в Python, которая запускается во время обработки IOT Analytics и отправляет два последовательных запроса POST на внешний API (если выполняется условие). Я не могу напрямую импортировать пакет "запрос", поскольку он слишком велик для встроенного редактирования, поэтому я загрузил свой скрипт Python, а также пакет в zip-файл, а затем загрузил его в AWS.
При запуске лямбда я получаю ошибки в файлах пакетов запросов, которые я не совсем понимаю. Я также не уверен, как вернуть ответ API, так как в моем ответе появляется ошибка сериализации. Вот мой лямбда-код:
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
}
Вы знаете, как исправить эти ошибки?
Если я изменю значение возврата на "reponse_1: json.dumps(response1)", я получу следующие ошибки (будь то с zip-пакетом или 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"
2 ответа
Похоже, что библиотека 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)
}
Что-то странное для меня заключается в том, что, если я не включаю response_1 и response_2 в возвращаемое значение, функция выполняется и отправляет обратно статус 200, при этом 'exec_verif' является "отправленным запросом 2", в то время как фактического вызова функции внешний API. В журналах API нет никаких следов вызовов, даже неудачных.
Использование кодировки base64 сработало для меня. Пример приведен здесь; https://docs.aws.amazon.com/apigateway/latest/developerguide/lambda-proxy-binary-media.html
Подробнее здесь; https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-workflow.html