К подготовке и публикации первого пакета Python готовы!

Python стал одним из самых широко используемых языков программирования. Главным образом объясняется это тем, что мы, его обычные пользователи, можем поделиться своим кодом, обеспечивая другим возможность беспрепятственно им пользоваться. А сделать это можно общепринятым способом, упаковав весь код и загрузив его в каталог программного обеспечения Python (Python Package Index или PyPI), с помощью которого пользователи легко и просто установят ваш пакет, используя инструмент pip. 

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

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

Для работы с текущим руководством представим, что директория со всеми файлами Python, включая нужный нам python_file_0.py, называется test_package. Именно этот пакет мы и намерены опубликовать. Следуя принципу простоты, файл python_file_0.py содержит лишь следующий код, который будет использован по мере нашей готовности импортировать пакет после его публикации: 

def hello_world():
    print("Hello World!")

1. Подготовка файлов 

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

the_root_dir/
|-- README.md
|-- setup.py
|-- test_package
|   |-- __init__.py
|   |-- python_file_0.py
|   |-- python_file_1.py
|   |-- python_file_2.py
  • В корневой директории на одном уровне с test_package создайте файл README.md. Он будет содержать необходимую пользователям информацию о пакете, например сведения об установке и инструкции по применению. 
  • На этом же уровне находится файл setup.py. Он будет включать информацию, необходимую для подготовки пакета к публикации. Вскоре мы рассмотрим содержимое этого файла. 
  • В директории test_package создайте файл __init__.py именно с таким именем. Он трансформирует обычную директорию в пакет Python. Для этого простого пакета просто поместим код в python_file_0.py и экспортируем from test_package.python_file_0 import hello_world.

Файл README 

Теоретически для этого файла можно использовать простой текст, но отдав предпочтение файлу Markdown, вы получите разные возможности форматирования и таким образом сделаете его более интересным для чтения. Ниже показан пример простого файла README.md:

Это тестовый пакет, представляющий собой часть обучающего руководства Meduim. 

**Текст жирным шрифтом** 

*Текст, выделенный курсивом* 

## Лицензия 
Лицензия MIT

Обратите внимание, что основное содержание сохраняется как файл TXT, показывающий исходный текст для Markdown, перед тем как Github автоматически применит форматирование для файлов Markdown. 

Как правило, рекомендуется включать информацию о лицензии пакета, чтобы пользователи знали условия его использования. В нашем случае просто укажем лицензию MIT. 

Файл setup

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

import setuptools

with open("README.md") as file:
    read_me_description = file.read()

setuptools.setup(
    name="test-package-username",
    version="0.1",
    author="Your Name",
    author_email="your_email",
    description="This is a test package.",
    long_description=read_me_description,
    long_description_content_type="text/markdown",
    url="package_github_page",
    packages=['test_package'],
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.5',
)
  • Сначала мы импортируем модуль setuptools, содержащий удобные методы настройки упаковки. 
  • В вызове функции setup() большинство параметров очень простые и не требуют пояснений. Рассмотрим основные моменты: 

name. Имя дистрибутива пакета, которое на pypi.org должно быть уникальным. Хороший способ обеспечить эту уникальность  —  присоединить к имени пакета имя пользователя в PyPI. 

long_description. Из файла README.md обычно устанавливается подробное описание. Для его корректного отображения вы указываете, что это файл Markdown, задавая параметр long_description_content_type.

packages. Перечень пакетов, подлежащих публикации в пакете дистрибутива. Поскольку мы публикуем только один пакет test_package, то в списке значится именно его имя. Однако если вы планируете опубликовать все пакеты директории, то для удобства их извлечения используйте setuptools.find_packages()

python_requires. Указывает необходимую для пакета версию Python.  

2. Подготовка к загрузке 

Регистрация аккаунта PyPI 

В большинстве случаев при упоминании PyPI имеется ввиду обычный веб-сайт (https://pypi.org/), где регистрируются пакеты Pyhton. Однако существует еще его альтернативная версия (https://test.pypi.org/), предназначенная для тестирования без нарушения официальной индексации. 

Обратите внимание, что для этих двух сайтов создаются отдельные аккаунты. В нашем случае мы будем использовать тестовый сайт. Переходите по ссылке и регистрируйте свой аккаунт: https://test.pypi.org/account/register/.

Создание API-токена 

После регистрации аккаунта рекомендуется создать API-токен для загрузки пакета. Перейдите в раздел API tokens в настройках и кликните “Add API token.” 

Следуйте инструкциям, чтобы создать API-токен. Укажите его область действия (scope) применительно к конкретным или ко всем проектам. После этого важно сохранить токен, чтобы впоследствии можно было к нему вернуться, поскольку в целях безопасности нельзя пересоздавать или восстанавливать уже существующий токен.  

Установка инструментов архивации и загрузки 

Надо сказать, что для архивации и загрузки пакетов Python существуют различные инструменты. Мы задействуем те из них, которые чаще всего используются для дистрибуции: setuptools, wheel и twine.

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

python3 -m pip install --user --upgrade setuptools wheel twine

3. Дистрибуция пакета 

Архивация пакета 

Архивация  —  первый этап подготовки пакета к дистрибуции. В терминале перейдите в корневую директорию, содержащую все файлы пакета, например setup.py, и выполните следующую команду: 

python3 setup.py sdist bdist_wheel

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

the_root_dir/
|-- .eggs
|   |-- a bunch of files in this directory
|-- build
|   |-- a bunch of files in this directory
|-- dist
|   |-- test-package-username-0.1.tar.gz
|   |-- test_package_username-0.1-py3-none-any.whl
|-- test_package
|   |-- the original files in the package
|-- test_package_username.egg-info
|   |-- a bunch of files in this directory
|-- README.md
|-- setup.py
|-- test_package

В частности, как показано выше, в директории dist он создаст два ключевых файла, готовых к загрузке. 

Загрузка пакета 

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

python3 -m twine upload --repository testpypi dist/*

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

Если всё сделано правильно, то загрузка пакета пройдет гладко. Однако в случае возникновения каких-либо сложностей, в файле setup.py обычно предоставляется подробная информация о возможных ошибках. Исправив их, вы сможете двигаться дальше. 

4. Тестирование пакета 

Просмотр пакета на PyPI 

Загрузив в TestPyPI пакет, вы можете перейти на его страницу и проверить, всё ли правильно отображается, например описания. В нашем случае после загрузки вы напрямую оказываетесь на веб-сайте https://test.pypi.org/project/test-package-username/0.1.1/. Из следующего скриншота видно, что подробное описание, изложенное в нашем файле README.md, отображается корректно: 

Импорт пакета 

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

pip install -i https://test.pypi.org/simple/ test-package-username==0.1.1

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

>>> from test_package import python_file_0
>>> python_file_0.hello_world()
Hello World!

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

Заключение 

В данной статье были рассмотрены 4 главных этапа создания пакета Python для дистрибуции на pypi.org. Хотя в нашем примере его публикация осуществлялась на тестовом варианте PyPI, точно таким же образом происходит процесс и на основном сайте каталога. 

Полезные ссылки 

  1. Знакомство с setuptools and setup.py (https://pythonhosted.org/an_example_pypi_project/setuptools.html).
  2. Упаковка проектов Python (https://packaging.python.org/tutorials/packaging-projects/).

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи Yong Cui, Ph.D.: How to Prepare and Publish Your First Python Package