Повторное использование кода — очень полезная штука. Вы экономите время при написание одних и тех же кусков кода, и даже в одном проекте у вас сохраняется модульная структура приложения, что позволяет поддерживать в актуальном состоянии каждый модуль отдельно от других. И в python довольно легко создать структуру приложения так, чтобы было легко его оформить в пакет. Этот гайд поможет вам научиться создавать такие пакеты с нуля так, чтобы другие люди могли воспользоваться им в своих приложениях.
Структура пакета
Файл с расширением ‘.py’ — это модуль. Вы можете создать в нём классы, функции и переменные с таким же именем, как у файла. А если в папку положить несколько модулей и создать файл ‘__init__.py’, вы создадите тем самым пакет с именем как у папки. Вот примерная файловая иерархия обычного пакета:
Сборка пакета
Теперь когда мы знаем структуру пакета, поговорим про его сборку. Самое важное здесь — конфигурационный файл ‘setup.py’. Основной смысл в нём — хранение метаданных о пакете. Вот пример такого файла:
from setuptools import setup, find_packages
setup(name='funniest',
version='0.1',
description='The funniest joke in the world',
long_description='Really, the funniest around.',
classifiers=[
'Development Status :: 3 - Alpha',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2.7',
'Topic :: Text Processing :: Linguistic',
],
keywords='funniest joke comedy flying circus',
url='http://github.com/storborg/funniest',
author='Flying Circus',
author_email='flyingcircus@example.com',
license='MIT',
packages=find_packages(),
install_requires=[
'markdown',
],
include_package_data=True,
zip_safe=False)
Более подробно об этом файле можно прочитать в документации.
Указываем зависимости
Для того, чтобы с пакетом можно было работать сразу после установки, вы должны указать в его конфигурации, от каких пакетов он зависит, чтобы они были сразу же установлены. Нужно просто вставить ‘install_requires=[…]’ в функцию setup. Можно также задать версию зависимости:
install_requires=[‘A==1.0’, ‘B>=1,<2’]
Эти зависимости — общедоступные пакеты, которые можно установить с помощью утилиты pip. Но если ваши зависимости не перечислены в каталоге pypi, укажите их так:
dependency_links=[‘http://github.com/user/repo/tarball/master#egg=package-1.0']
Дополнительные файлы
Иногда бывает необходимость вложить в пакет другие типы файлов. Для этого:
- Задайте ‘include_package_data=True’
- Создайте файл MANIFEST.in в папке с setup.py
- Добавьте путь до файла в MANIFEST как ‘include /path/to/test.json’, путь при этом относительный. Также можно использовать поисковый шаблон типа ‘*.json’.
Сборка
Теперь у нас всё готово, приступаем к сборке пакета. Это значит, что мы создадим дистрибутив исходного кода (напр., tar.gz) или бинарный файл (напр., wheel). Это очень просто.
python setup.py sdist bdist_wheel
В результате у нас в папке ‘./dist’ появятся оба формата. при этом имя дистрибутива будет присвоено исходя из имени пакета и его версии.
Распространение пакета
Поздравляю, вы создали замечательный пакет! Теперь необходимо выложить его для общего доступа. Мы загрузим его на Pypi, поэтому в будущем можно будет его установить командой ‘pip install’.
Для начала создайте учётную запись на сайте pypi.
Затем выполните
twine upload dist/*
При этом файлы из папки ‘dist/’ выгрузятся в каталог pypi. Также вы можете явно указать только определённый файл для выгрузки. Twine это специальная утилита для работы с pypi. При первой загрузке пакета она зарегистрирует пакет в pypi.
Работа с пакетом
Теперь ваш пакет опубликован в pypi. Для его установки достаточно набрать ‘pip install my_package’, а затем в коде ‘import my_package’.
При локальной разработке пакета для его тестирования добавьте путь к нему в $PYTHONPATH. Но если вы не хотите трогать переменные окружения, установите его командой ‘pip install -e .’ из папки с пакетом.
По материалам «A Simple Guide for Python Packaging»
Разработчик: java, kotlin, c#, javascript, dart, 1C, python, php.
Пишите: @ighar. Buy me a coffee, please :).