Практическое руководство по использованию setup.py
Оригинал статьи Rogier van der Geer: A Practical Guide to Using Setup.py от 25-03-2019.
Когда вы используете Python профессионально, выгодно настраивать свои проекты последовательно. Это поможет вашим соавторам быстро понять структуру проекта и упростит им настройку проекта на своей машине. Ключом к настройке вашего проекта является файл setup.py. В этом блоге я подробно расскажу об этом файле.
Где мы начинаем
Здесь я предполагаю, что у вас уже есть пакет, который вы хотите настроить. Это не обязательно должен быть готовый пакет - в идеале вам следует создать setup.py задолго до того, как ваш проект будет завершен. Это может быть даже пустой пакет; просто убедитесь, что папка пакета существует и содержит файл с именем __init__.py (который может быть пустым).
Если вы следуете структуре моего коллеги Хенка для вашего проекта, ваша начальная ситуация должна выглядеть примерно так:
example_project/
├── exampleproject/ Пакет Python с исходным кодом.
│ ├── __init__.py Сделайте папку пакетом.
│ └── example.py Пример модуля.
└── README.md README с информацией о проекте.В вашей структуре могут быть другие файлы или папки, например папки с именами notebooks/, tests/ или data/, но это не обязательно.
Случай для setup.py
После того, как вы создали такой пакет, вы, вероятно, использовать часть кода в других местах. Например, вы можете захотеть сделать это в блокноте:
from exampleproject.example import example_functionЭто будет работать, если ваш текущий рабочий каталог - exampleproject/, но в во всех остальных случаях python выдаст такой вывод:
ModuleNotFoundError: No module named 'exampleproject'Вы можете указать python, где искать пакет, установив переменную окружения PYTHONPATH или добавив пути к sys.path, но это далеко от идеала: потребуются разные действия на разных платформах, и путь, который вам нужно установить, зависит от местоположения вашего кода. Гораздо лучший способ - установить ваш пакет с помощью setup.py и pip, поскольку pip - это стандартный способ установки всех других пакетов, и он связан он работает одинаково на всех платформах.
Минимальный пример
Так как же выглядит файл setup.py? Вот минимальный пример [0]:
Здесь мы указываем три вещи:
Имя пакета name, которое будет использовать pip для вашего пакета. Это не обязательно должно совпадать с именем папки, в которой находится пакет, хотя, если это не так, это может сбить с толку. Пример того, где находится пакет имя и каталог не совпадают - Scikit-Learn: вы устанавливаете его используя
pip install scikit-learn, но вы используете его путем импорта из sklearn.Версия вашего пакета version. Это версия, которую сообщит pip, и она используется например, когда вы публикуете свой пакет на PyPI
[1].Какие пакеты включать packages; в нашем случае это просто
exampleproject/. Здесь мы позволяем setuptools понять это автоматически[2]. Хотя вы в принципе можете использоватьfind_packages ()без каких-либо аргументов это может потенциально привести к тому, что нежелательные пакеты могут быть включены. Это может случиться, например, если вы включили__init__.pyв свой каталогtests/. В качестве альтернативы вы также можете использовать аргумент exclude, чтобы явно предотвратить включение тестов в пакет, но это немного менее прочный.
Теперь все, что вам нужно сделать, чтобы установить ваш пакет, - это запустить следующий внутри каталога exampleproject/ [3]:
Здесь . относится к текущему рабочему каталогу, который, как я полагаю, является каталогом, в котором можно найти setup.py. Флаг -e указывает, что мы хотим установить в редактируемом режиме, что означает, что при редактировании файлов в нашем пакете нам не нужно переустанавливать пакет до того, как изменения вступят в силу. Вам нужно будет либо перезапустить python, либо перезагрузить пакет!
Когда вы редактируете информацию в самом файле setup.py, вам в большинстве случаев потребуется переустановить пакет, а также при добавлении новых (под)пакетов. Если есть сомнения, переустановка никогда не повредит. Просто запустите pip install -e . в очередной раз.
Requirements
У большинства проектов есть зависимости. Скорее всего, вы раньше использовали файл requirements.txt или environment.yml, если используете conda. Теперь, когда вы создаете setup.py, вы можете указать свои зависимости в аргументе install_requires. Например, для типичного проекта по науке о данных у вас может быть:
Вы можете указать требования без версии (PyYAML), закрепить версию (pandas==0.23.3), указать минимальную версию (numpy>=1.14.5) или установить диапазон версий (matplotlib>=2.2.0, <3.0.0). Эти требования будут автоматически установлены pip при установке пакета.
Extras-require
Иногда у вас могут быть зависимости, которые требуются только в определенных ситуациях. Как специалист по данным, я часто создаю пакеты, которые использую для обучения модели. Когда я работаю над такой моделью в интерактивном режиме, мне может потребоваться установить matplotlib и jupyter для интерактивной работы с данными и создания визуализаций производительности модели. С другой стороны, если модель запускается в производственной среде, я не хочу устанавливать matplotlib или jupyter на машине (или контейнере), где я тренируюсь или делаю вывод. К счастью, setuptools позволяет указывать необязательные зависимости в extras_require:
Теперь, если мы установим пакет обычным образом (pip install example из PyPI или pip install -e . локально), он установит только зависимости PyYAML, pandas и numpy. Однако, когда мы укажем, что нам нужны дополнительные зависимости interactive (pip install example [interactive] или pip install -e . [interactive]), тогда также будут установлены matplotlib и jupyter.
Скрипты и точки входа
Основной вариант использования большинства пакетов Python, которые вы устанавливаете из PyPI, заключается в предоставлении функциональности, которая может использоваться в другом коде Python. Другими словами, вы можете импортировать из этих пакетов. Как специалист по данным, я часто делаю пакеты, которые не предназначены для использования другим кодом Python, но предназначены для чего-то, например, для обучения модели. Таким образом, у меня часто есть скрипт python, который я хочу выполнить из командной строки.
Лучший способ [4] раскрыть функциональность вашего пакета в командной строке - это определить точка входа как таковые:
Теперь вы можете использовать команду my-command из командной строки, которая, в свою очередь, выполнит функцию main внутри exampleproject/example.py. Не забудьте переустановить - иначе команда не будет зарегистрирована.
Тесты
Всякий раз, когда вы пишете какой-либо код, я настоятельно рекомендую вам также писать тесты для этого кода. Для тестирования с помощью python я предлагаю вам использовать pytest. Конечно, вы не хотите добавлять pytest к своим зависимостям в install_requires: это не требуется пользователям вашего пакета. Чтобы он устанавливался автоматически при запуске тестов, вы можете добавить в файл setup.py следующее:
Кроме того, вам необходимо создать файл с именем setup.cfg со следующим содержимым:
Теперь вы можете просто запустить python setup.py test, и setuptools обеспечит установку необходимых зависимостей и запустит pytest за вас! Посмотрите здесь, если вы хотите предоставить аргументы или установить параметры конфигурации для pytest.
Если у вас есть дополнительные требования для тестирования (например, pytest-flask), вы можете добавить их в tests_require.
Flake8
Лично я считаю, что запустить Flake8 для проверки форматирования вашего кода - хорошая идея. Как и в случае с pytest, вы не хотите добавлять flake8 в зависимости install_requires: его не нужно устанавливать, чтобы использовать ваш пакет. Вместо этого вы можете добавить его в setup_requires:
Теперь вы можете просто запустить python setup.py flake8. Конечно, вы также можете закрепить версию flake8 (или любого другого пакета) в setup_requires.
Если вы хотите изменить некоторые параметры конфигурации Flake8, вы можете добавить раздел [flake8] в свой setup.cfg. Например:
Данные пакета
Иногда вы можете захотеть включить в свой пакет некоторые файлы, отличные от Python. Это могут быть, например, файлы схемы или небольшая таблица поиска. Имейте в виду, что такие файлы будут упакованы вместе с вашим кодом, поэтому, как правило, включать любые большие файлы - плохая идея.
Предположим, у нас есть schema.json в нашем проекте, который мы помещаем в exampleproject/data/schema.json. Если мы хотим включить это в наш пакет, мы должны использовать аргумент package_data в настройке:
Это гарантирует, что файл включен в пакет. Мы также можем включить все файлы на основе шаблона, например:
Это добавит все файлы *.json в любой встреченный пакет.
Теперь не пытайтесь самостоятельно определить расположение установленных файлов, поскольку pkg_resources имеет несколько очень удобных функций:
pkg_resources.resource_stream предоставит вам поток файла, очень похожий на объект, который вы получаете при вызове open (),
pkg_resources.resource_string предоставит вам содержимое файла в виде строки,
pkg_resources.resource_filename предоставит вам имя файла (и извлечет его во временное хранилище, если он включен в заархивированный пакет) на случай, если два указанных выше варианта не соответствуют вашим потребностям.
Например, мы можем читать в нашей схеме, используя:
Метаданные
Если вы собираетесь опубликовать свой пакет, вы, вероятно, захотите предоставить своим потенциальным пользователям дополнительную информацию о вашем пакете, включая описание, имя автора или сопровождающего и URL-адрес домашней страницы пакета. Вы можете найти полный список всех разрешенных метаданных в документации setuptools.
Кроме того, если вы собираетесь публиковать в PyPI, вы можете автоматически загрузить содержимое вашего README.md в long_description и предоставить классификаторы classifiers, чтобы сообщить pip еще больше о вашем пакете.
Подведение итогов
Этот блог должен стать хорошей отправной точкой для настройки большинства ваших проектов на Python. Если вы хотите узнать больше о упаковке Python, загляните в документацию. Вот пример setup.py, который объединяет все части, показанные в этом блоге:
и сопутствующий setup.cfg:
Совершенствуйте свои навыки Python, учитесь у экспертов!
В GoDataDriven мы предлагаем множество курсов Python от новичка до эксперта, которые проводят лучшие профессионалы в этой области. Присоединяйтесь к нам и повышайте уровень своей игры на Python:
Python Essentials - Отлично, если вы только начинаете работать с Python.
Certified Data Science with Python Foundation - Хотите сделать шаг от анализа и визуализации данных к настоящей науке о данных? Это правильный курс.
Advanced Data Science with Python - Научитесь создавать свои модели как профессионал и использовать Python для машинного обучения.
Сноски
[0]- В этом блоге я использовал setuptools для создания моего примера проекта. В качестве альтернативы вы также можете использовать distutils, который является стандартным инструментом для упаковки в python, но в нем отсутствуют такие функции, как функция find_packages () и entry_points. Поскольку использование setuptools в настоящее время очень распространено, и многие из его функций могут быть особенно полезными, я предлагаю вам использовать setuptools.[1]- Если вы хотите, чтобы версия вашего пакета также была доступна внутри python, загляните сюда.[2]- Вы также можете перечислить свои пакеты вручную, но это особенно подвержено ошибкам.[3]- В качестве альтернативы вы можете запуститьpython setup.py install, но при использовании pip множество преимуществ, среди которых автоматическая установка зависимостей и возможность удалить или обновить ваш пакет.[4]- Вы также можете использовать аргумент scripts (см., например, здесь), но поскольку для этого требуется создать сценарий оболочки Python, он может не работать (или вообще) в Windows.
Last updated