Python Poetry: Поэма об управлении зависимостями в Python

Инженер-программист компании ESK Solutions.

Случалось ли вам начинать новый Python-проект или пересматривать старый, и в процессе настройки окружения получать назойливое сообщение "невозможно установить зависимость X, поскольку версия пакета имеет конфликтующие зависимости" с зависимостями проекта? Затем вы проверили файл требований и обнаружили, что у нарушенной зависимости нет прикрепленной версии, или, что еще хуже, ее вообще нет. Вы не одиноки, со мной такое случалось раз или два.

Когда такое случается, лучшим решением всегда является следующее:

  1. Проверить версию у другого сотрудника.
  2. Добавить ее в файл требований
  3. Заново запустить процесс установки
  4. Надеяться, что это не произойдет со следующей зависимостью.
  5. Повторить .

Вы видите, что это очень реактивный процесс, потому что он не предотвращает повторения ситуации, а рано или поздно это произойдет. Эта мысль не давала мне покоя. Есть ли решение этой распространенной проблемы? Что-то вроде npm для front-end проектов?

Старый способ

Обычный способ установки зависимостей в Python-проект - это использование pip. С помощью pip вы добавляете зависимость командой pip install X, а затем записываете ее с привязкой к версии (например, requests==2.26.0) в файл requirements.txt, так что в следующий раз новичку достаточно выполнить pip install -r requirements.txt, чтобы установить их.

Python Poetry CLI с командами, TOML и файлами блокировок.

Проблема такого подхода заключается в том, что если у зависимостей есть подзависимости, то не всегда можно получить одну и ту же версию, поскольку они не указаны в файле requirements.txt. Другая проблема этого процесса заключается в том, что вы можете забыть добавить зависимость в файл требований. Именно здесь на помощь приходит Python Poetry.

Чем привлекателен Python Poetry

Poetry использует TOML-файл вместо текстового файла для отслеживания зависимостей, а также файл блокировки для отслеживания зависимостей и подзависимостей. При каждой установке зависимостей проекта вы всегда будете получать те же версии, что и в файле блокировки. Poetry идет дальше и сохраняет хэш пакета, поскольку некоторые сопровождающие могут обновлять пакет, не меняя его версию.

Poetry поставляется с удобным CLI для установки зависимостей, поэтому pip больше не нужен. При установке зависимостей они автоматически добавляются в файл TOML, избавляя вас от необходимости запоминать пакеты, которые вы добавляете в проект.

Python Poetry принудительно использует виртуальные среды. Если вы еще не используете виртуальную среду, она создаст новую виртуальную среду для изоляции зависимостей между различными проектами. Если вы используете Docker, то можете отключить эту функцию, поскольку нет смысла использовать виртуальные среды внутри контейнеров.

В отличие от старого способа, Poetry дает возможность обновлять все пакеты, причем в зависимости от используемой спецификации зависимостей это может быть патч или незначительное обновление (для крупных обновлений рекомендуется тщательное исследование).

Спецификация зависимостей - это ограничение по версии, которое вы применяете к своим зависимостям. Вы можете использовать ограничения в виде каретки, тильды или подстановочного знака, или даже указать диапазон допустимых версий. Также можно использовать git, путь и URL, а также зависимости от источника.

Еще одной приятной особенностью Poetry является то, что при удалении зависимости, которая вам больше не нужна, удаляются и ее подзависимости, чего не происходит в случае с pip. Это позволяет избежать появления "сиротских" зависимостей в вашем окружении.

Наконец, Poetry дает возможность отделить основные зависимости, необходимые для работы проекта, от зависимостей разработки, которые используются в основном для отладки. Это позволяет получить производственную среду, свободную от ненужных зависимостей.

Следует отметить, что Poetry также умеет упаковывать и публиковать библиотеки, но я остановлюсь только на управлении зависимостями.

Составление первой поэмы

Нет лучшего способа понять что-то, чем увидеть своими глазами, поэтому мы проведем небольшое руководство по переносу существующего проекта на Python Poetry. Я буду считать, что у вас уже установлен Python версии 3.7+ и git. Если вы чувствуете в себе смелость, вы можете использовать проект, который у вас есть или с которым вы работаете, но я предоставлю макет Django-проекта для этого урока. Версия Python Poetry на момент написания этой статьи - 1.3.1.

Разработчик Python озадачен файлом requirements.txt.

Прежде всего, вы можете установить Python Poetry, выполнив команду:

curl -sSL https://install.python-poetry.org | python3-

Проверить, что Poetry успешно установлен, можно, выполнив команду poetry -version. Также можно выполнить команду poetry list для отображения списка доступных команд.

Теперь, когда сценарий готов, приступим к миграции.

Инициализация Poetry 

Первым шагом будет инициализация Python Poetry в проекте, поэтому выполните команду poetry init внутри репозитория. Появится интерактивное приглашение для настройки TOML-файла. Вы можете использовать предложения по умолчанию, но убедитесь, что ваша версия Python соответствует полю Compatible Python version. Когда вы дойдете до раздела "Хотите ли вы определить свои основные зависимости интерактивно?", просто напишите "нет". Затем появится вопрос, хотите ли вы задать зависимости для разработки в интерактивном режиме; снова напишите "нет". Наконец, появится запрос на подтверждение настроек; отправьте "да".

Перенос зависимостей

Поскольку у вас уже есть файл requirements.txt, проще всего перенести зависимости, выполнив команду:

cat requirements.txt | xargs poetry add

Poetry добавит каждую зависимость в TOML-файл и попытается разрешить все конфликты, после чего запишет файл блокировки. Если вы не используете виртуальную среду, то зависимости будут установлены во вновь созданную виртуальную среду.

Теперь, когда poetry имеет в своем списке все ваши зависимости, вы можете проверить их, запустив poetry show. 

Поскольку файл requirements.txt больше не нужен, от него можно избавиться.

Очистка вложенных зависимостей

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

Выполните команду:

poetry show --tree

И вы увидите, какие из них являются подзависимостями.

Создание обновляемых зависимостей

Последний шаг - сделать зависимости обновляемыми. Лично я использую только обновления патчей, поскольку они обычно содержат исправления и патчи безопасности. Минорные и мажорные обновления я делаю только после того, как прочитаю списки изменений и буду уверен, что это то, что мы хотим добавить в проект.

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

Теперь зависимости Django и djangorestframework могут получать обновления (патчи). В следующий раз, когда будет выпущено обновление для любой из этих зависимостей, вы можете обновить их командой:

poetry update

При этом будет сделана попытка обновления всех зависимостей. Вы также можете указать, какие именно зависимости необходимо обновить. В случае если обновления будут найдены, Poetry разрешит конфликты зависимостей и запустит обновление. После этого он обновит файл блокировки.

В данном случае, если вы запустите обновление и, предположим, внесете те же изменения, что и я, вы увидите, что djangorestframework обновится с версии 3.10.0 до 3.10.3, которая является последним патчем на момент написания этой статьи.

Команда разнообразных Python-разработчиков работает на экране компьютера.

Дальнейшие шаги

С этого момента вы можете использовать Poetry для добавления и удаления зависимостей из вашего проекта, используя только CLI. В случае, если вы сделаете обновление вне ограничений, вам нужно будет выполнить команду add с новой версией.

Для новичков в проекте получить точно такие же версии пакетов, как и у того, кто последний раз обновлял файл блокировки, достаточно просто выполнить команду poetry install.

Подведение итогов

Подобно npm, Python Poetry является мощным инструментом для управления зависимостями, который решает многие проблемы, возникающие при использовании файла requirements.txt вместе с pip. Он также обладает большей функциональностью, а CLI очень прост в использовании. Его можно применять как к новым, так и к существующим Python-проектам, что позволяет легко добавлять, удалять и обновлять зависимости по мере развития проекта.