Pipfile.lock → requirements.txt
Коротко
Обновление
Как указали мне в комментариях к англоязычной версии этой заметки, в релизе v2022.4.8 добавили команду, которая это делает:
|
|
Документация для новой команды тут.
Старый вариант
Для requirements.txt
:
|
|
Для requirements-dev.txt
:
|
|
Пояснение
Я много использую Пайтон на работе и Pipenv для управления виртуальными окружениями и пакетами в них.
Pipenv хранит все зависимости в файле с названием Pipfile
, и записывает их конкретные версии (те, что сейчас
установлены) в Pipfile.lock
.
Несмотря на то, что это незаменимый инструмент в процессе разработки, иногда возникает необходимость вернуться к старым
файлам requirements.txt
.
Они используются для установки зависимостей через стандартный менеджер пакетов pip
:
|
|
В качестве примера я буду использовать создание образа для докера с пайтоном внутри.
В моём случае, первой проблемой было поведение pipenv install
.
Интуитивно кажется, что эта команда должна установить зависимости из файла Pipfile.lock
— с их конкретными версиями.
Однако, на деле оказалось, что под капотом сначала запускается команда lock
, которая обновляет версии пакетов в
файле Pipfile.lock
до наиболее свежих, совместимых с ограничениями версий, прописанными в Pipfile
.
И уже после этого запускает команду sync
, которая устанавливает зависимости из lock-файла.
Это может не быть большой проблемой, если ограничения по версиям в Pipfile
достаточно строгие.
Но это зачастую не так и помимо этого всегда есть риск получить «неудачное» минорное обновление.
В этом случае можно получить сломанный образ и долго искать причину — когда локально всё работает.
После выяснения этих деталей я перешёл на использование pipenv sync
напрямую.
Однако, позже обнаружилась другая проблема: очередное обновление сломало Pipenv так, что пришлось откатываться на более раннюю версию и фиксировать её в Dockerfile, чтобы избежать такого в дальнейшем.
После этого у меня появилась идея о том, в наличии Pipenv внутри контейнера нет необходимости. Всё, что эта утилита
делает в контейнере — это чтение зависимостей из Pipfile.lock
и запуск pip для их установки.
А для этого достаточно иметь лишь requirements.txt
.
Существует официальный способ
для генерации requirements.txt
с помощью Pipenv:
|
|
Это работает, однако, имеет упомянутый выше побочный эффект — обновление версий и возможное несовпадение зависимостей
как следствие. И нет альтернативной команды: pipenv sync -r
.
Кто-то даже создал утилиту для генерации requirements-файлов из lock-фала, называется pipenv-to-requirements. Я её не пробовал, потому что нашёл способ получше.
Периодически мне приходится работать с json-файлами в терминале.
Для этого есть замечательный инструмент jq, рекомендую с ним познакомиться, если вы этого ещё не сделали.
Так как Pipfile.lock
— это обычный json-файл, логично предположить, что с помощью jq можно трансформировать его в
формат requirements.txt
.
Вот что получилось:
|
|
- флаг
-r
нужен для того, чтобы убрать кавычки из выходных данных - часть
.defailt
получает содержимое секцииdefault
внутриPipfile.lock
, заменив её на.develop
можно сгенерироватьrequirements-dev.txt
to_entries[]
трансформирует пары ключ-значение из объекта на предыдущем шаге:package: info
трансформируется в{"key": package, "value": info}
и пакуется в массив.key + .value.version
составляет строку из названия пакета и его точной версии
Загляните в Pipfile.lock
для лучшего понимания.