Coder Social home page Coder Social logo

poetry-presentation's Introduction

Доклад: библиотека Poetry

Доклад подготовлен в рамках курса ФКН НИУ ВШЭ "Язык программирования Python (углубленный курс)".

Содержание

Введение

Система управления пакетами (или же «пакетный менеджер») — инструмент, позволяющий управлять процессом установки, обновления и удаления различных компонентов программного обеспечения, например, библиотек для Python, которые вы можете использовать в работе над собственной программой. Одним из таких менеджеров является Poetry. Позволим Poetry представить себя самостоятельно [docs]:

Poetry — это инструмент для управления зависимостями в Python. Он позволяет фиксировать библиотеки, от которых зависит ваш проект, и он будет управлять (устанавливать / обновлять) их для вас. Poetry использует lockfile для обеспечения воспроизводимой установки зависимостей и может упаковать ваш проект для распространения.

Ни добавить, ни убавить. Вам нужен NumPy / pandas / Django / <что-нибудь еще>? Тогда Poetry спешит к вам.

pip VS poetry

«Стоп», — возможно, скажете вы, — «но я все время делал(-a) что-то вроде pip install package_name», — и будете совершенно правы. Pip — это тоже пакетный менеджер, да еще какой, ведь он устанавливается вместе с Python (практически всегда) по умолчанию. Более того, pip является старичком в своем деле. Впервые он был представлен в 2008 году, а в релиз с версией 1.0 вышел в 2011 [proof]. С тех пор прошло много лет, прежде чем в 2018 году [check here] свет увидела самая первая версия Poetry, 0.1.0.

Сегодня Poetry подрос, окреп и собрал целых 27 500 звезд на GitHub.

Но у pip побольше? А вот и нет — 9 000. Конечно, это не говорит о том, что Poetry используется разработчиками чаще, чем встроенный pip, но как минимум говорит о том, что «фанатов» у первого больше.

Чем же обусловлены появление и взлет Poetry? Конечно, причин несколько. На этом этапе мы не будем вдаваться в подробности, но посмотрим на слабые места pip и на альтернативу, которую предлагает Poetry.


Файл с зависимостями

Pip хранит список зависимостей проекта в файле с расширением *.txt. Этот файл принято называть requirements.txt, его можно встретить во многих проектах.

Пример содержимого requirements.txt
fastapi==0.103.2
uvicorn[standard]==0.23.2

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

Пример содержимого pyproject.toml
[tool.poetry]
name = "poetry-presentation"
version = "0.1.0"
description = "A very cool description"
authors = ["Grigory Yolkin <[email protected]>",]
license = "MIT"
readme = "readme.md"

[tool.poetry.dependencies]
python = "^3.8"
fastapi = "^0.103.2"
uvicorn = {extras = ["standard"], version = "^0.23.2"}

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Помимо самих зависимостей под tool.poetry.dependencies, можно также заметить tool.poetry и build-system. Об их предназначении поговорим позже, а пока сделаем главный вывод, который напрашивается после увиденного: Poetry в одном месте хранит зависимости и некоторую другую информацию о проекте, что может быть удобно в ряде случаев.

Сила pyproject.toml

Надо признать, файл pyproject.toml носит весьма общее название. Кажется, он не так прост, как кажется из примера выше. Так и есть! Сила pyproject.toml в том, что этот файл в качестве файла конфигурации помимо Poetry используют такие утилиты, как black, mypy, ruff, coverage, pytest и другие. Это значит, что в том же месте помещается ряд полезных настроек проекта, отвечающих за зависимости, форматирование, линтинг, тестирование кода и т.д.

Разделение зависимостей

Еще одна актуальная для многих разработчиков проблема заключается в необходимости разделения зависимостей. Вот, например, утилита black, использующаяся для форматирования кода, очень полезна в процессе разработки, но не нужна в продакшене. Мы можем установить зависимости из файла при помощи pip вот так:

pip install -r requirements.txt

То есть рекурсивно устанавливаем каждую зависимость из requirements.txt, никак не разделяя пакеты, необходимые в продакшене, при разработке или тестировании проекта. Нехорошо, особенно если таких зависимостей много. Poetry предлагает филигранное решение проблемы, о котором мы вскоре обязательно поговорим.


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

Подробнее про pyproject.toml

Сначала посмотрим на уже известные нам из примера выше tool.poetry и build-system. После разберемся с остальными тегами, которые вы можете встретить или внести в pyproject.toml.

build-system

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

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Если вам интересно узнать больше про build-system, то вы можете прочитать об этом в PEP 517.

tool.poetry

Ключевой для Poetry тег в pyproject.toml. Он содержит в себе несколько секций, настраивает Poetry для вашего проекта в целом.

name

Обязательное поле, означающее название вашего проекта. PyPI (Python Package Index) ограничивает названия такой регуляркой, но без учета регистра:

^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$

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

import re

pattern = r'^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$'
project_title = "string"
print(bool(re.fullmatch(pattern, project_title, re.IGNORECASE)))

version

Обязательное поле, означающее версию проекта. Значение должно быть строкой наподобие "0.1.0". Но возможны и менее стандартные варианты, если это необходимо, например, "1.0.0.post1". Подробнее про это можно прочитать в PEP 440.

description

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

authors

Обязательное поле. Представляет из себя список авторов проекта, перечисленных через запятую в формате name <email>.

license

Опциональное поле, означающее лицензию продукта. Наиболее популярные Apache 2.0 и MIT. Это поле можно не заполнять, однако крайне рекомендуется это сделать, если вы создаете open-source проект. Подробнее про лицензии можете почитать на Хабре. Статья была написана в далеком 2014 году, но не потеряла в актуальности.

maintainers

Опциональное поле. Представляет из себя список людей, поддерживающих проект (англ. maintainer — хранитель, сопровождающий). Люди в списке должны отличаться от авторов, перечисляются в таком же формате.

readme

Опциональное поле, указывающее путь до README-файла. Может принимать список путей, если таких файлов несколько. Если вы собираетесь опубликовать результат своей работы в PyPI, то рекомендуется заполнить это поле. Файл README может содержать в себе различную информацию, например, намного более длинное и детальное описание, чем в description.

homepage, repository, documentation

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

keywords

Опциональное поле, содержащее список ключевых слов, связанных с проектом.

classifiers

Опциональные поле, содержащее список PyPI классификаторов проекта.

packages

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

Итак, тег tool.poetry может содержать в себе разнообразные данные, которые можно включать или исключать по своему усмотрению. Если вы не планируете публиковать проект в PyPI или выкладывать его в публичный доступ, но используете Poetry, то можно обойтись самым минимумом информации. Если же ваша цель заключается в том, чтобы показать свое творение миру, то, наверное, подробности не помешают — это сделает проект более прозрачным и подскажет другим разработчикам, в каком направлении он двигается.

tool.poetry.group

Poetry позволяет разделить список зависимостей вашего проекта по группам. Must-have зависимости, которые необходимы проекту в продакшене, указываются в tool.poetry.dependencies, а вот с зависимостями для разработки возможно некоторое творчество. Например, представим, что мы используем type-checker и форматер — mypy и black, для тестирования — pytest, а mkdocs для документирования проекта. Тогда в pyproject.toml можно разбить dev-зависимости на группы в зависимости от их предназначения:

[tool.poetry.dependencies]
# основные зависимости
[tool.poetry.group.test.dependencies]
pytest = "*"
pytest-mock = "*"
[tool.poetry.group.docs.dependencies]
mkdocs = "*"
[tool.poetry.group.tools.dependencies]
black = "*"
mypy = "*"

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

tool.poetry.scripts

Под этим тегом вы можете описать любые сценарии или скрипты, которые необходимо воспроизвести при установке пакета. Если, например, у вас в проекте есть какая-то консольная утилита, которая генерирует своеобразный dependency report (указывая на уязвимости, актуальные обновления и т.д), то ее может быть очень кстати запускать, используя tool.poetry.scripts.

tool.poetry.extras

Список дополнительных зависимостей, которые можно установить, а можно и не устанавливать. Можно также собрать кластеры зависимостей, т.е. несколько дополнительных зависимостей, объединенных под одним кодовым словом для быстрой комплексной установки. В документации Poetry приводится такой пример:

[tool.poetry.dependencies]
# ...
psycopg2 = { version = "^2.9", optional = true }
mysqlclient = { version = "^1.3", optional = true }

[tool.poetry.extras]
mysql = ["mysqlclient"]
pgsql = ["psycopg2"]
databases = ["mysqlclient", "psycopg2"]

Это может быть полезно при работе с различными СУБД, администраторскими панелями и инструментами кастомизации кода.

tool.poetry.plugins

Poetry поддерживает встраивание различных плагинов. В общем виде синтаксис определения плагина в файле pyproject.toml выглядит следующим образом:

[tool.poetry.plugins]  # опционально

[tool.poetry.plugins."A"]
"B" = "C:D"
  • A: тип плагина,
  • B: название плагина,
  • C: путь к соответствующему Python-модулю,
  • D: entry point плагина (т.е. функция или класс, которые его запускают).

Взглянем на конкретный пример, чтобы лучше понять, как это работает:

[tool.poetry.plugins."poetry.application.plugin"]
poetry-dotenv-plugin = "poetry_dotenv_plugin.dotenv_plugin:DotenvPlugin"

В данном случае мы добавляем в проект Poetry Dotenv Plugin. Его предназначение в том, чтобы автоматически загружать переменные окружения из .env файла перед выполнением команд Poetry. Больше плагинов вы можете найти, например, на GitHub. Среди них есть много тех, что заслуживают внимания и действительно могут прокачать ваш DX при работе с проектом.

tool.poetry.urls

Под этим тегом можно указать какие-то дополнительные URL, кроме упомянутых выше homepage, repository или documentation. После публикации в PyPI все ссылки из этого раздела попадут в секцию Project Links.

Установка Poetry

Вкратце резюмируем, что нам известно о Poetry на данный момент:

  • Это пакетный менеджер, помогает управлять зависимостями в вашем проекте;
  • Он мощнее, чем pip, которым вам, возможно, уже приходилось пользоваться;
  • Poetry конфигурируется в общем для разных утилит файле pyproject.toml и представляет возможность использовать весьма тонкие настройки.

Впечатляюще. Однако, чтобы попробовать Poetry, его нужно сначала установить. Может, это покажется забавным, но проще всего сделать это через pip (в глобальном окружении):

pip install poetry

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

Инициализация проекта

Конечно, руками создавать и заполнять pyproject.toml необходимости нет. Установив Poetry в систему, мы получаем возможность использовать консольные команды (CLI) для работы с пакетными менеджером. Прямо так, как раньше мы это делали с pip. Воспользуемся магической командой:

poetry new poetry-demo

И, после непродолжительного ожидания, получим папку poetry-demo со следующим содержимым:

poetry-demo
├── pyproject.toml
├── README.md
├── poetry_demo
│   └── __init__.py
└── tests
    └── __init__.py

Poetry подготовил для нас структуру проекта, которая включает в себя README файл, тот самый pyproject.toml с базовыми настройками, папку poetry_demo (по названию проекта, которое мы указали) и папку tests.

А что насчет существующего проекта? Конечно, чтобы использовать Poetry необязательно все начинать с чистого листа. Добавить этот пакетный менеджер можно и в уже существующий проект. В корне необходимо выполнить следующую команду:
poetry init

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

Виртуальное окружение

По умолчанию Poetry создаст папку с виртуальным окружением в {cache-dir}/virtualenvs. В Windows, например, полный путь из диска C будет выглядеть как-то так: C:/Пользователи/User/AppData/Local/pypoetry/Cache/virtualenvs/*. Это может быть несколько непривычно для тех, кто привык генерировать venv (или env, или как-то еще) папку прямо в папке проекта. Зато это освобождает от необходимости каждый раз записывать папку с виртуальным окружением в .gitignore. Тем не менее в этом аспекте Poetry сохраняет приверженность гибкости и позволяет изменить стандартный путь, установив новый путь в качестве значения для переменной окружения POETRY_CACHE_DIR [подробности].

Основные команды

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

Шаблон команды в консоли выглядит стандартно:

poetry <command>

install

Если вы работали с pip, то можете неправильно воспринимать команду poetry install — здесь она служит инструментом для установки всех зависимостей, перечисленных в pyproject.toml, а не для установки какого-то конкретного пакета.

Немного про управление зависимостями

Выше мы говорили о том, что Poetry позволяет гибко определять и устанавливать зависимости. Это достигается в том числе за счет команды install, поскольку можно установить флаг --without, чтобы установить зависимости, исключая все зависимости из каких-либо групп. Например, если у вас есть группы зависимостей test и docs, установить зависимости без этих групп можно следующим образом:

poetry install --without test,docs

Кроме того, есть флаги --only, --with и --only-root. Флаг --only служит для установки зависимостей только из определенных групп. Флаг --with для выбора групп зависимостей, которые мы хотим установить. Флаг --only-root позволит установить сам проект, без зависимостей.

После установки: lockfile

После установки зависимостей будет создан файл poetry.lock, который содержит информацию о них, а также их зависимостей.

update

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

poetry update

Команда поддерживает уже известные нам флаги --only, --without и --with. Алгоритм работы у нее простой: сначала обновляется lockfile, затем все зависимости устанавливаются в проект (устаревшие заменяются на новые). Если вы не хотите автоматически устанавливать все зависимости, но хотите обновить lockfile, то можно применить флаг --lock.

add

Эту команду можно назвать аналогом команды pip install. Однако она не только устанавливает требуемый пакет в виртуальное окружение, но и добавляет запись о новой зависимости в pyproject.toml. Кроме того, команда поддерживает специфический синтаксис, позволяя гибко определять необходимые зависимости:

# Различные варианты установки pendulum
poetry add "pendulum>=2.0.5"
poetry add pendulum==2.0.5
poetry add pendulum@latest
poetry add git+https://github.com/sdispater/pendulum.git

# Установка mkdocs в группу зависимостей docs
poetry add mkdocs --group docs

В общем случае хватит выполнить просто:

poetry add pendulum

Если хотите оценить все возможности Poetry в вопросе установки зависимостей, то смело обращайтесь к этому разделу документации.

remove

Команда для удаления зависимости из проекта. Можно указать флаг --group, как и в случае с add, чтобы удалить зависимость из конкретной группы.

poetry remove pendulum

Как и другие команды, автоматически обновляет poetry.lock и pyproject.toml.

show

Еще одна интуитивно понятная команда! poetry show выводит список имеющихся зависимостей, это своеобразный аналог pip list. Кстати, можно вывести довольно детальную информацию о конкретной зависимости:

poetry show pendulum

# пример вывода
name        : pendulum
version     : 1.4.2
description : Python datetimes made easy

dependencies
 - python-dateutil >=2.6.1
 - tzlocal >=1.4
 - pytzdata >=2017.2.2

required by
 - calendar >=1.4.0
# Выведет дерево зависимостей проекта, иногда полезная вещь
poetry show --tree

list

Сразу поговорим о list, чтобы не путать команду с уже упомянутым pip list. В Poetry эта команда служит чем-то вроде типичной справки: выводит список всех команд Poetry. Кстати, очень рекомендуем изучить его.

run

С помощью данной команды вы можете выполнить какую-то другую команду внутри виртуального окружения проекта. Также вы можете выполнить скрипт, определенный в [tool.poetry.scripts].

poetry run python -V
# или
poetry run black .

shell

Команда для создания виртуального окружения для проекта, если оно еще не создано. Автоматически активирует виртуальное окружение.

poetry shell

Активировать виртуальное окружение при последующей работе над проектом можно с помощью команды poetry env use python, Poetry все сделает за вас. Более подробная информация про команду env и управление виртуальными окружениями содержится в документации Poetry.

build и publish

Пара специфических команд, необходимых для тех, кто работает над open-source пакетом, который в будущем планирует опубликовать. Так, дистрибутив простого проекта можно собрать командой poetry build:

poetry build

# пример вывода
Building bye (0.1.0)
  - Building sdist
  - Built bye-0.1.0.tar.gz
  - Building wheel
  - Built bye-0.1.0-py3-none-any.whl

Команда poetry publish автоматически отправит собранный дистрибутив в удаленный репозиторий, по умолчанию это PyPI. Команда предусматривает использование таких флагов, как --username, --password, --cert и других, чтобы загрузка произошла успешно. Подробнее про них можно прочитать в документации.

Критика Poetry

Может показаться, что Poetry — превосходное решение, лишенное всяких недостатков, что, конечно, неверно. Poetry точно можно назвать all-in-one solution, но не идеальным и безупречным подходом к управлению зависимостями в проекте. Некоторые разработчики критикуют Poetry, часто эта критика небеспричинна. Например, на YouTube есть видеоролик, который называется why I will never use python-poetry. Его стоит посмотреть, если вы собираетесь использовать Poetry. Автор критикует пакетный менеджер по нескольким линиям, среди которых:

  • Большое количество зависимостей у самого Poetry (около 50 штук). Вы можете взглянуть на poetry.lock файл. Да, Poetry использует Poetry. Извините за частое упоминание слова Poetry.
  • Подход Poetry к управлению зависимостями по умолчанию. Так, при установке новой зависимости в проект с помощью команды poetry add <package> без всякой спецификации требуемой версии, в pyproject.toml будет записно что-то вроде ^<version>. То есть версия большая или равная указанной, но меньшая чем следующий major-релиз. В перспективе это может привести к конфликтам версий среди различных библиотек.
  • И некоторые другие вещи...

Впрочем, не зря существуют другие относительно популярные пакетные менеджеры, как, например, более совершенный вариант pip — pip-tools от известной команды разработчиков JazzBand.

Заключение

Попробуйте работать с Poetry. Это один из инструментов, который точно стоит попробовать в своей практике. Он мощнее и интереснее, чем многие аналоги, а для старта работы требует незначительных действий: быстрой установки и применения пары консольных команд.

poetry-presentation's People

Contributors

gyolkin avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.