Лямбда-функция запускается в IoT Analytics, которая отправляет запросы POST на внешний API - PullRequest
0 голосов
/ 27 марта 2020

Я пытаюсь установить AWS лямбда-функцию в Python, которая запускается во время обработки IOT Analytics и отправляет два последовательных запроса POST во внешний API (если выполняется условие). Я не могу импортировать пакет «request» напрямую, так как он слишком велик для встроенного редактирования, поэтому я загрузил свой сценарий Python и пакет в zip-файл, а затем загрузил его в AWS. * 1001. *

При запуске лямбды я получаю ошибки в файлах пакетов запросов, которые я не совсем понимаю. Я также не уверен, как вернуть ответ 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"

1 Ответ

0 голосов
/ 01 апреля 2020

Похоже, что 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 нет.

...