Pipenv + AWS Lambda
Суть
|
|
Взято отсюда.
Пояснения
Виртуальное окружение
Я сейчас много работаю с компонентами AWS и с AWS Lambda в частности. Писать код для лямбд можно на нескольких языках — на текущий момент поддерживаются Node.js, Java, Python и C#. Мы в команде используем пайтон. Так как до сих пор в ходу две его основных версии и для разных проектов могут требоваться различные версии библиотек, для управления версиями самого языка и пакетов принято использовать виртуальное окружение (virtual environment).
Традиционно виртуальное окружение создавалось следующим образом:
|
|
Первая команда создаёт чистый дистрибутив с пайтон 3 в локальной директории _env
.
Вторая команда активирует виртуальное окружение — изменяет переменную окружения PATH
, добавляет VIRTUAL_ENV
и стирает PYTHONHOME
.
После этого команды pip
, pip3
, python
и python3
будут работать в контексте дистрибутива в директории _env
.
Деактивировать виртуальное окружение можно командой deactivate
, которая вернёт переменным окружения изначальные значения.
Следующий шаг в настройке среды для разработки — это установка зависимостей.
Если проект распространяется в виде пакета, то зависимости указываются в файле setup.py
.
Для проектов, которые не предполагается распространять или подключать как зависимости, используются файлы со списками зависимостей.
Название файла может быть любым, но обычно это requirements.txt
с зависимостями самого приложения и requirements-dev.txt
с опциональными зависимостями для разработки.
|
|
Деплой лямбды
Для того, чтобы загрузить код лямбды в AWS, его нужно упаковать в zip-архив со всеми зависимостями. Это удобно делать, если всё необходимое находится в одной директории. Порядок команд мы использовали следующий:
|
|
После этого можно запаковать содержимое директории _build
в архив и загрузить в AWS S3,
либо использовать расширение AWS Serverless Application Model (SAM), которое автоматизирует и упрощает процесс.
Мы используем последний вариант, но это отдельная тема.
И что не так?
У вышеописанного подхода есть один существенный недостаток и несколько несущественных.
Для указания версии зависимостей существует специальный стандарт PEP 440, который позволяет не фиксировать версию жёстко, а указать её в виде некоего правила. Обычно ограничиваются указанием версии, в рамках которой сохраняется обратная совместимость.
Например:
|
|
Проблема в том, что устанавливается последняя доступная версия,
поэтому действительные версии библиотек могут отличаться для двух идентичных вызовов pip install
.
Так, в примере с лямбдой, версия кода, протестированная разработчиком локально, может не совпадать с той, которая будет загружена на сервер, потому что установка зависимостей происходила в разные моменты времени.
Для решения этой проблемы менеджеры зависимостей других языков используют так называемые lock-файлы.
Например, популярный менеджер для PHP — Composer — использует composer.lock
, a NPM — для Node.js — использует package-lock.json
.
Эти файлы генерируются и обновляются автоматически при установке новых зависимостей или обновлении имеющихся
и содержат информацию о конкретных версиях зависимостей.
Это позволяет быть уверенным, что установка зависимостей из lock-файлов в любой момент даст идентичный результат.
Дополнительно имеются данные для проверки целостности, что позволяет заметить, если версия та же, но код зависимости всё же отличается.
Меньшей проблемой, на мой взгляд, является необходимость вручную создавать и активировать виртуальное окружение. При этом необходимо как-то понять, какую версию пайтона использовать.
Ещё не очень удобно самостоятельно указывать зависимости в requirements.txt
.
Были случаи, когда разработчик устанавливал зависимость во время разработки, но забывал вписать её в файл, из-за чего у коллег не запускался проект.
Pipenv
Проект pipenv призван избавить разработчика от обозначенных проблем.
|
|
Если в проекте уже существует Pipfile
, то настроить виртуальное окружение и установить зависимости можно одной командой:
|
|
Настроить окружение для разработки — тоже одной (при этом, предыдущую команду вызвать не требуется):
|
|
Если имеется Pipfile.lock
, то будут установлены именно те версии, которые в нём указаны.
Pipenv + AWS Lambda
Утилита pipenv относительно новая, находится в активной разработке и некоторых возможностей она не предоставляет, а некоторые планируют и вовсе убрать (например).
Для сборки пакета для лямбды критически важно иметь возможность установить зависимости в указанную директорию.
«Из коробки» pipenv такую функцию не поддерживает. Но, как всегда, есть ободные пути.
Один из них — это небольшой скрипт, который копирует исходники зависимостей из директории репозитория виртуального окружения. Другой — это генерация файла requirements.txt
и установка зависимостей по-старинке, с помощью традиционной утилиты pip.
Второй вариант умещается в однострочник (хотя это две команды, а не одна):
|
|
pipenv lock -r
генерирует список зависимостей, совместимый с синтаксисомrequirements.txt
pip install --target _build -r file
устанавливает зависимости из указанного файла в указанную директориюpipenv run
необходима, чтобы запуститьpip
в виртуальном окружении
Пошаговая инструкция
Начальные требования: установленные
homebrew
,
pipenv
и
python3
(желательно, но должно работать и с python2
).
|
|
Настройка окружения (в директории проекта):
|
|
Сборка и публикация кода для лямбды:
|
|
Это всё можно упаковать в Makefile и запускать одной командой.