Обработка изображений на AWS Lambda и API Gateway за 10 минут

Давайте узнаем, сможем ли мы создать простое приложение на Python 3.6, которое:

  • Конвертирует обычную фотографию в черно белую фотографию;
  • Использует OpenCV.

Доступно через API, которое

  • Принимает бинарные данные (jpeg)
  • Возвращает бинарные данные (jpeg)

Работает без

  • без готового сервера
  • без оплаты (за исключением случаев, где ваш трафик превысит бесплатный пакет Lambda)

Для начала, установим Docker.

Для этого примера мы используем сервис от AWS под названием Lambda, который позволит вам развернуть вашу функцию и ее зависимости, а также легко подключить ее к API. Чтобы создать API, мы воспользуемся API Gateway — еще один сервис, предоставляемый AWS.

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Для простоты данного руководства, мы развернем наш код, загрузив его в Lambda через веб консоль AWS. Мы также напишем код нашей функции внутри консоли AWS, чтобы сохранять процесс максимально простым. В любом другом случае вам нужно выполнять развертывание через AWS CLI.

1. Начнем с входа в консоль AWS и поиск Lambda.

Обработка изображений на AWS Lambda и API Gateway за 10 минут

2. Нажимаем на Create function (создать функцию).

Обработка изображений на AWS Lambda и API Gateway за 10 минут

3. Настраиваем параметры функции.

Мы назовем нашу функцию lambda-demo. Нужно убедиться, что мы работаем с Python 3.6 в качестве среды выполнения и создайте новую роль из шаблонов политики AWS.

Обработка изображений на AWS Lambda и API Gateway за 10 минут

4. После создания функции, вам дадут определенный шаблонный код в консоли Lambda.

Вы можете сразу вызвать эту функцию, настроив тестовое событие. Нажмите на Test и настройте первое тестовое событие. Для целей данной статьи, шаблон по умолчанию работает как надо.

Обработка изображений на AWS Lambda и API Gateway за 10 минут

Обработка изображений на AWS Lambda и API Gateway за 10 минут

После создания тестового события, нажмите Test. Вы должны получить следующее в логах функции:

Отлично.

Теперь создадим что-нибудь более полезное.

Построим функцию, которая получает изображение и делает её черно-белым. Для этого мы воспользуемся OpenCV. Кроме этого, использование OpenCV может быть идеальным для такой задачи, она показывает, как такая полезная библиотека может быть добавлена в вашу среду Lambda с относительной легкостью.

Сейчас мы сделаем следующее:

  1. Генерируем заточенный под Python пакет Lambda для OpenCV.
  2. Загрузим пакет в Lambda Layers, так что он может быть использован в любой функции, которую вы создаете.
  3. Импортируем OpenCV в нашу функцию Lambda.

Генерация заточенного под Python пакет Lambda для OpenCV

Я собрал очень простой инструмент — образ Docker, который может получить любой пакет pip и генерировать .ZIP, который мы можем загружать в Lambda Layers. Если вы хотите изучить этот инструмент, вы можете найти его в LambdaZipper.

Если у вас есть установленный Docker, вы можете открыть терминал и запустить следующее:

Это все! В вашей текущей рабочей папке вы можете найти opencv-python.zip

Один из самых полезных безсерверных наборов инструментов — это serverless. Однако мы не будем использовать его в данном примере. Изобретение велосипеда далеко не всегда хорошая идея, за исключением тех случаев, когда вы хотите изучить, как и что устроено внутри. Несмотря на то, что такие продвинутые фреймворки как serverless существуют, хорошей идеей будет найти ряд корневых функций, которые эти фреймворки абстрагируют.

Давайте узнаем, что наш инструмент абстрагирует от нас.

Если вы взглянете на package.sh, то вы увидите, что он выполнил команду установки pip install с аргументом opencv-python. Все это было выполнено в среде amazonlinux:2017.03, которая в некоторой степени имитирует среду AWS Lambda. Вы можете изучить среду выполнения в Dockerfile.

Загрузка пакета в Lambda Layers для использования в любой из созданых функций

Давайте загрузим opencv-python.zip в Lambda Layers, чтобы мы могли использовать этот пакет во всех наших функциях. Относитесь к Layers как к данным, которые могут быть использованы в любой из написанных вами функций. Это могут быть модули Python, части кодов, бинарные файлы, и т.д.

Перейдите в панель Layers в AWS Lambda и нажмите создать слой (Create layer).

Обработка изображений на AWS Lambda и API Gateway за 10 минут

Укажите название слоя, его описание и загрузите zip файл. Убедитесь в том, что выбрали правильную среду выполнения (в нашем случае это Python 3.6). Нажмите создать слой (Create layer).

Обработка изображений на AWS Lambda и API Gateway за 10 минут

На момент написания этой статьи, загрузка zip файла из веб интерфейса ограничено 50МВ. К счастью, наш пакет opencv-python весит меньше. В случае, если ваш пакет весит больше, вы можете загрузить пакет в качестве ссылки из корзины S3. Обратите внимание на то, что Lambda указывает ограничение развертывание пакета в 250MB.

После создания функции, вас должно приветствовать уведомление:

Отлично!

Давайте вернемся к нашей lambda-demo функции Lambda и добавим слой opencv-python в среду выполнения нашей функции. Нажмите Layers > Add a layer, и выберите ваш слой opencv-python.

Импорт OpenCV

Давайте попробуем импортировать библиотеку стандартным образом:

После нажатия на Test, мы получим ответ:

По какой-то причине, Lambda на смогла найти наш пакет…

По умолчанию, все слои Lambda монтируются в /opt. Давайте уберём наш импорт модуля cv2 и взглянем на то, что внутри /opt.

В журналах функции мы можем увидеть наш модуль cv2 и numpy в /opt.

По умолчанию, /opt/bin внесен в переменную среды $PATH. Вы можете убедиться в этом в документации AWS. Однако наши модули слоя находятся в /opt/, а не в /opt/bin. Итак, давайте внесем /opt в $PATH, чтобы Lambda могла видеть наш пакет.

В разделе Environment Variables, внесите следующую переменную среды.

  • Ключ: PYTHONPATH
  • значение: /opt/

Обработка изображений на AWS Lambda и API Gateway за 10 минут

Как правило, вы можете просто импортировать пакет без изменения пути, но в нашем случае, это нужно для среды Lambda для обнаружения нашего пакета.

Давайте обновим наш код:

Сохраните изменения и нажмите Test. В консоли нас поприветствует 4.0.0, информируя о том, какая версия OpenCV используется.

Великолепно, OpenCV запустился в Lambda!

Давайте продолжим реализацию корневой логики приложения — конвертация изображений в черно-белый. Давайте обновим код функции Lambda.

API, который мы настроим буквально сейчас, будет принимать бинарное изображение от клиента. Бинарное изображение затем будет конвертировано в base64 через AWS API Gateway и передано в Lambda.

Разумеется, API Gateway еще не настроен, так что тестирование этого кода с нашим нынешним тестом приведет к неудаче. Однако, перед тем как мы перейдем к настройке API, который вызывает нашу Lambda, мы можем протестировать API в консоли Lambda, предоставив base64 кодированное изображение в теле событий.

Перенастраиваем Test с этим содержимым. Если вам интересно, это конвертированное в base64 изображение кошки 😺 https://imgur.com/a/0NpkzzL .

Обработка изображений на AWS Lambda и API Gateway за 10 минут

Вызов данного теста будет удачным:

Теперь мы готовы к настройке API, которая вызывает данную функцию Lambda.

Настройка API

Открываем консоль AWS API Gateway. Нажимаем Create API.

Обработка изображений на AWS Lambda и API Gateway за 10 минут

Создаем новый REST API, даем API название и описание. В данном случае, мы назовем наш API lambda-demo.

Обработка изображений на AWS Lambda и API Gateway за 10 минут

В Resources > Actions выбираем Create Method для определения метода POST.

Обработка изображений на AWS Lambda и API Gateway за 10 минут

Для типа интеграции выбираем Lambda Function и выбираем нашу функцию Lambda из выпадающего меню. Включите интеграцию Use Lambda Proxy и нажмите Save.

Обработка изображений на AWS Lambda и API Gateway за 10 минут

Нам нужно, чтобы наш API мог обрабатывать бинарные данные.

В Settings > Binary Media Types выбираем Add Binary Media Type и определяем тип двоичных данных как:

Нажимаем на Save Changes.

Обработка изображений на AWS Lambda и API Gateway за 10 минут

Переходим обратно в метод POST.

Под Method Response добавляем Content-Type Response Header и указываем тип image/jpeg:

Обработка изображений на AWS Lambda и API Gateway за 10 минут

Перед публикацией API, вы можете протестировать его, нажав на кнопку Client Test:

Обработка изображений на AWS Lambda и API Gateway за 10 минут

В нашем случае, мы предоставляем само тело изображения в base64, а не объект json. Для удобства, вы можете вставить необработанную строку base64 из следующей ссылки в поле Request Body (ссылка).

Ответом будет строка base64 черно-белой фотографии.

Обработка изображений на AWS Lambda и API Gateway за 10 минут

Нажмите Actions > Deploy API.

Создайте новый этап развертывания, дайте ему подходящее название, например development и нажмите Deploy.

Обработка изображений на AWS Lambda и API Gateway за 10 минут

API теперь опубликован и прекрасно работает! Вы получите url, в котором он развернут:

Давайте опробуем!

1. Загрузим то же изображение в нашу локальную среду:

2. Через Post-запрос отправим наше изображение в бинарном виде. Как результат, мы получим черно-белое изображение которая сохранилась с названием kitty_bw.jpg.

Учитывайте, что для простоты данной статьи, мы не рассматривали обработку ошибок, проверки запроса и настройку авторизации. Для производственного приложения это должно быть настроено в API Gateway и в коде функции вашей Lambda.