Как опубликовать Python-пакет в PyPI с помощью Poetry

от автора

Предыстория

Недавно я решил создать свой первый Python-пакет и опубликовать его в PyPI. После месяца написания и тестирования кода я наконец подготовил всё к публикации. Так как для меня это был новый опыт, по пути я столкнулся с несколькими подводными камнями, поэтому решил поделиться пошаговой инструкцией, как сделать то же самое.

Мой пакет можно посмотреть на GitHub и на PyPI.

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

Подготовка аккаунта на PyPI

Для начала понадобится аккаунт. Перейдите на PyPI и создайте аккаунт, после чего завершите настройку профиля.

Генерация API-токена на PyPI

Чтобы публиковать пакет в PyPI, понадобится API-токен для вашего аккаунта. После регистрации откройте страницу аккаунта, прокрутите вниз до секции API tokens и нажмите кнопку Generate API token.

Укажите имя токена и область действия. Если у вас пока нет опубликованных проектов на PyPI, вы сможете создать только токен уровня аккаунта. Он подойдёт для публикации новых пакетов. Сохраните этот токен — он понадобится позже.

Подготовка проекта

Сначала создайте директорию, в которой будут храниться файлы пакета. Далее создайте виртуальное окружение Python. Я предпочитаю создавать виртуальные окружения прямо в папке проекта, хотя poetry умеет создавать его и в {cache-dir}/virtualenvs.

python3 -m venv .venvsource .venv/bin/activate

После создания виртуального окружения нужно установить и инициализировать poetry:

pip install poetrypoetry init

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

[tool.poetry]name = "pypi-poetry-publish-example"version = "0.1.0"description = ""authors = ["Author <email@email.com>"]readme = "README.md"packages = [{include = "pypi_poetry_publish_example"}][tool.poetry.dependencies]python = "^3.10"[build-system]requires = ["poetry-core"]build-backend = "poetry.core.masonry.api"

Разберём основные поля файла:

  • name — имя проекта. По умолчанию Poetry берёт имя папки, в которой была выполнена инициализация.

  • version — версия проекта. Она будет использоваться при публикации пакета.

  • python — минимальная или совместимая версия Python для проекта.

  • build-system — система сборки, которая используется для создания source distribution и wheel.

  • readme — файл, который будет использоваться как описание пакета. Если это поле указано, файл должен существовать в корне проекта.

После настройки poetry создадим новую папку pypi_poetry_publish_example, в которой будут храниться файлы пакета. Внутри неё создадим файл core.py.

Важно: имя папки с исходным кодом пакета должно соответствовать имени проекта из pyproject.toml, но записываться через подчёркивания.

В нашем случае:

pypi-poetry-publish-example (pyproject.toml) → pypi_poetry_publish_example (имя папки)

# core.pyPREPEND_STR = 'prepend_'def modify_str(string: str) -> str:    return f'{PREPEND_STR}{string}'

Также хорошей практикой будет добавить файл LICENSE. Часто для этого используют лицензию MIT.

После этого зафиксируем версии зависимостей:

poetry lock

В итоге структура проекта будет выглядеть так:

pypi-poetry-publish-example/├── LICENSE├── poetry.lock├── pyproject.toml├── README.md├── pypi_poetry_publish_example/       ├── __init__.py       └── core.py

Сборка и публикация пакета

Проект готов к публикации, но перед этим нужно собрать source archive и wheel. Для этого используется команда:

poetry build

Перед публикацией нужно настроить API-токен:

poetry config pypi-token.pypi pypi-XXXXXXXX

где pypi-XXXXXXXX — это API-токен, который вы сгенерировали в аккаунте.

После этого можно загрузить пакет в PyPI командой:

poetry publish

Готово — пакет опубликован. Проверить это можно на странице проектов.

Теперь пакет можно установить так:

pip install pypi-poetry-publish-example

Дополнительные зависимости

В приведённом примере зависимости не использовались. При необходимости их можно добавить через Poetry. После установки они появятся в секции tool.poetry.dependencies и будут обязательны для установки вместе с пакетом.

Возможно, вы встречали команды вида:

pip install somepackage[extra]

Такой синтаксис устанавливает дополнительные, опциональные возможности пакета. Они не будут устанавливаться автоматически, если выполнить только pip install somepackage.

Чтобы настроить это в своём проекте, нужно добавить флаг optional к зависимости, которую вы хотите сделать необязательной, а затем перечислить её в секции [tool.poetry.extras].

Например, pyproject.toml с опциональной зависимостью pydantic будет выглядеть так:

[tool.poetry]name = "pypi-poetry-publish-example"version = "0.1.0"description = ""authors = ["Author <email@email.com>"]readme = "README.md"packages = [{include = "pypi_poetry_publish_example"}][tool.poetry.dependencies]python = "^3.10"pydantic = {version=">=1.9", optional = true}[tool.poetry.extras]pydantic = ["pydantic"][build-system]requires = ["poetry-core"]build-backend = "poetry.core.masonry.api"

ссылка на оригинал статьи https://habr.com/ru/articles/1024972/