
Предыстория
Недавно я решил создать свой первый 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/