Запуск функции Lambda с событием JSON

AWSBeginner
Практиковаться сейчас

Введение

Команде оформления покупок нужна функция, которая рассчитывает сумму заказа. Вы развернёте короткий обработчик Python, отправите два входных объекта JSON и добавите в расчёт сбор за обработку. Используйте целое число центов для простой арифметики, затем удалите свою функцию и журналы.

Сначала выполните Get Started with AWS on LabEx, Использование временных учётных данных с ролью IAM и Поиск неудачного запроса в CloudWatch Logs. Эта свежая среда предоставляет CLI, рабочую папку и роль выполнения.

Связь с сертификацией

Эта лабораторная работа помогает на практике изучить следующие темы экзаменов.

Разверните расчёт заказа

На этом шаге вы замените незавершённый обработчик и развернёте функцию. AWS Lambda запускает ваш код при вызове функции. Событие — входные данные этого вызова; обработчик — функция Python, которую Lambda вызывает с этими данными. Настройка app.handler означает функцию с именем handler в app.py.

Перейдите в подготовленную рабочую папку и изучите каркас. Сейчас он возвращает пустой объект, поэтому не может рассчитать заказ.

cd /home/labex/project
cat app.py

Python использует отступы для группировки инструкций внутри функции. event["quantity"] читает значение из входного объекта JSON. * умножает количество на цену единицы; return отправляет вычисленный объект вызывающей стороне. context предоставляет информацию о вызове, хотя этому расчёту она пока не нужна.

Замените каркас этим полным обработчиком. cat > app.py записывает в файл строки между <<'PY' и закрывающим PY. Закрывающая строка должна стоять отдельно.

cat > app.py <<'PY'
import json

def handler(event, context):
    order_id = event["order_id"]
    quantity = event["quantity"]
    unit_price = event["unit_price_cents"]
    total = quantity * unit_price
    print("EVENT " + json.dumps(event))
    return {"order_id": order_id, "total_cents": total}
PY

Инструкция print записывает входные данные в журналы выполнения; она не возвращает ответ. Не помещайте секреты клиентов в журналы. Эти события содержат только синтетические идентификаторы и числа.

Создайте пакет Zip — архив, который развёртывает Lambda. Поместите app.py на его верхний уровень, чтобы обработчик можно было найти. Роль выполнения — идентичность, которую Lambda использует при запуске вашего кода. Эта подготовленная роль поддерживает запись журналов; доступ к данным вы настроите в последующей работе. Прочитайте её ARN в переменную оболочки. ARN определяет конкретный ресурс; переменная избавляет от ручного копирования.

zip -q function.zip app.py
ROLE_ARN=$(aws iam get-role --role-name labex-fn01-execution --query 'Role.Arn' --output text)

Разверните функцию со средой выполнения Python 3.12 и тайм-аутом в пять секунд. fileb:// читает архив как байты. Среда выполнения выбирает языковое окружение; тайм-аут ограничивает один вызов.

aws lambda create-function --function-name labex-fn01-quote --runtime python3.12 --handler app.handler --role "$ROLE_ARN" --zip-file fileb://function.zip --timeout 5 --query '{Name:FunctionName,Runtime:Runtime,Handler:Handler,Timeout:Timeout,CodeSize:CodeSize}'

Ожидайте Name labex-fn01-quote, Runtime python3.12, Handler app.handler, Timeout 5 и положительное CodeSize. Создание функции развёртывает код; оно не вызывает обработчик.

AWS View отображает функцию, обработчик и отпечаток кода. Журналы вызовов ещё пусты. Эталонная группа журналов — независимые данные платформы, которые должны остаться неизменными.

Вызовите функцию с двумя событиями JSON

На этом шаге вы вызовете развёрнутую функцию с двумя разными заказами и интерпретируете её ответы. JSON представляет объект с именованными полями. Числа записываются без кавычек; строки — в кавычках. Каждый вызов получает собственное событие.

Развёртывание сохраняет пакет кода; вызов передаёт событие и запускает его обработчик.

Запишите первое событие: два товара по 375 центов каждый.

cat > small.json <<'JSON'
{"order_id":"fn01-small","quantity":2,"unit_price_cents":375}
JSON

Вызовите функцию и сохраните её ответ. --cli-binary-format raw-in-base64-out позволяет CLI принимать обычный JSON как полезную нагрузку. file:// читает текст события; последний файл принимает возвращённую полезную нагрузку.

aws lambda invoke --function-name labex-fn01-quote --cli-binary-format raw-in-base64-out --payload file://small.json small-response.json
cat small-response.json

Команда сообщает StatusCode 200. Файл ответа должен содержать {"order_id":"fn01-small","total_cents":750}. Статус запроса к сервису и данные, возвращённые обработчиком, — разные доказательства; изучите и полезную нагрузку.

Отправьте второй заказ без повторного развёртывания кода. Пять товаров по 120 центов должны дать другую сумму.

cat > large.json <<'JSON'
{"order_id":"fn01-large","quantity":5,"unit_price_cents":120}
JSON
aws lambda invoke --function-name labex-fn01-quote --cli-binary-format raw-in-base64-out --payload file://large.json large-response.json
cat large-response.json

Ожидайте {"order_id":"fn01-large","total_cents":600}. Входные значения определяют вычисление той же функции.

В AWS View сравните идентификаторы заказов, количества, цены и суммы. Конфигурация функции остаётся прежней, а записи вызовов меняются. Откройте Show logs для любого заказа, чтобы увидеть его входные данные и возвращённый результат.

Обновите код и проследите его результат

На этом шаге вы добавите сбор за обработку в 100 центов и подтвердите, что новый вызов выполняет обновлённый расчёт. Редактирование локального app.py не меняет развёрнутый код; обновите пакет и отправьте его в Lambda.

Замените обработчик этой редакцией. Меняется только расчёт: + 100 добавляет сбор после умножения.

cat > app.py <<'PY'
import json

def handler(event, context):
    order_id = event["order_id"]
    quantity = event["quantity"]
    unit_price = event["unit_price_cents"]
    total = quantity * unit_price + 100
    print("EVENT " + json.dumps(event))
    return {"order_id": order_id, "total_cents": total}
PY
zip -q function.zip app.py
aws lambda update-function-code --function-name labex-fn01-quote --zip-file fileb://function.zip --query '{Name:FunctionName,CodeSHA:CodeSha256}'

Развёртывание возвращает имя и SHA-отпечаток кода. AWS View показывает изменённый отпечаток; прежние результаты вызовов остаются в журналах.

Для сравнения с Console официальный пример показывает файл Python рядом с элементами управления Deploy и Test. Его lambda_function.py и lambda_handler соответствуют app.py и handler этой работы; здесь продолжайте работать через Terminal.

Официальный пример Lambda Console с файлом Python и элементами управления развёртыванием.

Источник: Руководство AWS Lambda.

Используйте количества первого заказа с новым идентификатором сопоставления.

cat > revised.json <<'JSON'
{"order_id":"fn01-revised","quantity":2,"unit_price_cents":375}
JSON
aws lambda invoke --function-name labex-fn01-quote --cli-binary-format raw-in-base64-out --payload file://revised.json revised-response.json
cat revised-response.json

Ожидайте {"order_id":"fn01-revised","total_cents":850}: 750 центов за товары плюс сбор в 100 центов. Первый ответ остаётся равным 750; обновление кода не переписывает историю.

Журналы выполнения хранятся в /aws/lambda/<function-name>. Получите сообщения, содержащие этот идентификатор заказа, чтобы связать событие с вычисленным ответом.

aws logs filter-log-events --log-group-name /aws/lambda/labex-fn01-quote --filter-pattern '"fn01-revised"' --query 'events[].message'

Ожидайте входные данные EVENT и возвращённый объект с суммой 850. Полные потоки также содержат начало и конец вызова и отчёты среды выполнения, отдельно от ответа заказа.

Вернитесь в AWS View. Сравните три фактические записи, откройте Show logs для fn01-revised и сопоставьте его входные данные с результатом в 850 центов. Эталонные данные остаются неизменными.

Развёрнутая редакция возвращает 850 центов, а прежние вычисленные суммы и эталонные журналы остаются неизменными.

Удалите функцию и сохраните эталонные журналы

На этом шаге вы удалите только функцию и её группу журналов выполнения, затем подтвердите сохранность независимой эталонной группы. Функция и группа журналов — отдельные ресурсы; удаление одной функции не удаляет сохранённые журналы.

Удалите точно указанную функцию, затем успешно прочитайте список.

aws lambda delete-function --function-name labex-fn01-quote
aws lambda list-functions --query 'Functions[].FunctionName'

Ожидайте пустой список. Ошибка аутентификации или подключения не доказала бы удаление.

Удалите журналы выполнения работы и получите список оставшихся групп.

aws logs delete-log-group --log-group-name /aws/lambda/labex-fn01-quote
aws logs describe-log-groups --query 'logGroups[].logGroupName'

Должна остаться только /labex/labex-fn01-reference. Прочитайте её сообщение, чтобы доказать сохранность независимых данных при очистке.

aws logs get-log-events --log-group-name /labex/labex-fn01-reference --log-stream-name platform --query 'events[].message'

Ожидайте INFO platform reference keep unchanged. AWS View показывает отсутствие развёрнутой функции и журналов вызовов, а эталонная группа остаётся. Подготовленные роль и идентичность — компоненты среды; отзыв учётных данных и выключение следуют после проверки ресурсов.

Резюме

Вы написали обработчик Python, развернули пакет Zip и вычислили суммы из двух событий JSON. Вы обновили развёрнутый расчёт, сопоставили его новый результат с журналами выполнения и удалили только функцию и её группу журналов, сохранив эталонные данные.