Не удается запустить AWS Lambda-функцию с API Gateway

#python #python-3.x #amazon-s3 #aws-lambda

#python #python-3.x #amazon-s3 #aws-lambda

Вопрос:

Я создал простую лямбда-функцию python 3.7:

 import json
import boto3

s3 = boto3.client("s3")


def lambda_handler(event, context):
    bucket = "nubi-data"
    key = "core/user.json"

    try:
        data = s3.get_object(Bucket=bucket, Key=key)
        json_data = data['Body'].read()

        #return json_data

        return {
            'statusCode': 200,
            "headers": {"Content-Type": "application/json"},
            'body': json.loads(json_data)
            }


    except Exception as e:
        print(e)
        raise e
  

Эта функция считывает файл json из корзины s3. Файл json выглядит следующим образом:

{ «id»: 1, «name»: «John», «pwd»: «password»}

Функция успешно запускается при тестировании с экрана редактора функций в консоли AWS со следующим выводом: введите описание изображения здесь

Ответ: { «StatusCode»: 200, «headers»: { «Content-Type»: «application / json»}, «body»: { «id»: 1, «name»: «John», «pwd»: «password» } }

Идентификатор запроса: «f57de02f-44dd-4854-9df9-9f3a8c90031d»

Журналы функций: НАЧАЛЬНЫЙ запрос: f57de02f-44dd-4854-9df9-9f3a8c90031d Версия: $ ПОСЛЕДНЯЯ КОНЕЧНЫЙ запрос: f57de02f-44dd-4854-9df9-9f3a8c90031d ИДЕНТИФИКАТОР запроса ОТЧЕТА: f57de02f-44dd-4854-9df9-9f3a8c90031d Длительность: 260,70 мс Продолжительность выставления счета: 300 мс Объем памяти: 128 МБ Максимальное количество используемой памяти: 84 МБ

Но когда я тестирую функцию с API Gateway, я получаю сообщение об ошибке
введите описание изображения здесь

Чт, 21 марта, 21:04:08 UTC 2019: Тело ответа конечной точки перед преобразованиями: {«StatusCode»: 200, «headers»: {«Content-Type»: «application / json»}, «body»: {«id»: 1, «name»: «John», «pwd»: «password»}} Чт 21 марта 21:04:08 UTC 2019: Сбой выполнения из-за ошибки конфигурации: неверно сформированный ответ прокси-сервера Lambda Чт 21 марта 21:04:08 UTC 2019: Метод завершен со статусом: 502

Ответ №1:

Изменить

 'body': json.loads(json_data)
  

Для

 'body': json.dumps(json_data)
  

API Gateway ожидает строку в качестве выходных данных и json.dumps делает именно это. json.loads с другой стороны, создает JSON из строки. Если вы знаете NodeJS, они эквивалентны JSON.stringify и JSON.parse соответственно.

Пример

 json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
  

выдает

‘[«foo», {«bar»: [«baz», null, 1.0, 2]}]’

в то время как

 json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
  

выдает

[u’foo’, {u’bar’: [u’baz’, Нет, 1.0, 2]}]

Эта информация доступна в официальных документах

Редактировать

Еще одна вещь, которую мы с OP пропустили, заключается в том, что data['Body'].read() возвращает не сам JSON, а буфер. Сначала ее необходимо декодировать.

json_data = data['Body'].read().decode('utf-8') уже вернет stringified JSON (просто потому, что ваш файл является JSON, конечно), поэтому в вашем заявлении return вы должны быть в состоянии просто сделать это следующим образом:

 return {
         'statusCode': 200,
         "headers": {"Content-Type": "application/json"},
         'body': json_data
     }
  

Комментарии:

1. Я тоже пробовал это. Вот ошибка, которую я получаю при использовании дампов: Чт 21 марта 22:10:53 UTC 2019: Сбой выполнения Lambda со статусом 200 из-за ошибки функции клиента: Объект типа bytes не сериализуем в формате JSON. Идентификатор лямбда-запроса: a3c6d525-d4c4-4bd0-a7fc-901a8bab8111 Чт 21 марта 22:10:53 UTC 2019: Метод завершен со статусом: 502