В этой статье в основном рассказывается о том, как упаковать и загрузить лично написанное приложение Python на официальный склад PyPI, чтобы его можно было устанавливать и использовать напрямую через pip и поддерживать в PyPI.
Распределение инструментов setuptools
Когда-то инструментом распространения для Python был distutils, но он не мог определить зависимости между пакетами. Setuptools — это его расширенная версия, которая может помочь нам лучше создавать и распространять пакеты Python, особенно пакеты со сложными зависимостями. Это восполняет этот недостаток, добавляя базовую зависимую систему и множество связанных функций. Он также предоставляет программу автоматического запроса пакетов для автоматического получения зависимостей между пакетами и завершения установки этих пакетов, что значительно снижает сложность установки различных пакетов и делает ее более удобной.
Обычная установка Python идет с setuptools, если нет, вы можете использовать pip для установки:
$ pip install setuptools
setuptools прост и удобен в использовании, просто напишите короткий установочный файл setup.py, чтобы упаковать приложение Python.
Первый установочный файл
Создайте новый установочный файл setup.py в каталоге learn_setup, а затем создайте пакет myapp для имитации пакета с исходным кодом:
. ├── myapp │ └── __init__.py └── setup.py
Содержимое простого файла setup.py выглядит следующим образом:
from setuptools import setup setup( name=’firstApp’, # Имя приложения version=’0.0.1′, # номер версии packages=[‘myapp’], # Python пакет включен в установочный пакет )
Создать колесо с установочным файлом
С помощью вышеуказанного файла setup.py мы можем открыть различные установочные пакеты, которые в основном делятся на две категории: sdist и bdist.
Source distribution
Использование sdist может быть упаковано в исходный дистрибутив, поддерживаемые форматы сжатия:
zip | zip file (.zip) | Windows по умолчанию |
gztar | gzip’ed tar file (.tar.gz) | Unix по умолчанию |
bztar | bzip2’ed tar file (.tar.bz2) | |
xztar | xz’ed tar file (.tar.xz) | |
ztar | compressed tar file (.tar.Z) | |
tar | tar file (.tar) |
$ python setup.py sdist —formats=gztar,zip
Теперь в каталоге больше каталогов dist и * .egg-info. Сохраненные нами пакеты хранятся в dist. Приведенная выше команда использует —formats Назначенная игра .tar.gz с .zip Пакет, если он не указан, будет упакован в соответствии с форматом по умолчанию для конкретной платформы, как показано в приведенной выше таблице.
Название пакета setup.py Определено в name , version И указанный формат пакета, например: firstApp-0.0.1.tar.gz.
Built distribution
Используя bdist, вы можете распечатать собранный дистрибутив. По сравнению с исходным пакетом, он быстрее устанавливается, потому что он предварительно собран:
Календарь на python (питон) #short
gztar | gzipped tar file (.tar.gz) | Unix по умолчанию |
bztar | bzipped tar file (.tar.bz2) | |
xztar | xzipped tar file (.tar.xz) | |
ztar | compressed tar file (.tar.Z) | |
tar | tar file (.tar) | |
zip | zip file (.zip) | Windows по умолчанию |
rpm | RPM | |
pkgtool | Solaris pkgtool | |
sdux | HP-UX swinstall | |
wininst | self-extracting ZIP file for Windows | |
msi | Microsoft Installer. |
В использовании, как sdist, вы можете использовать —formats Укажите формат пакета. Такие как:
$ python setup.py bdist —formats=rpm
Чтобы упростить операцию, setuptools предоставляет следующие команды:
bdist_dumb | tar, gztar, bztar, xztar, ztar, zip | Zip по умолчанию для Windows, gztar по умолчанию для Unix |
bdist_rpm | rpm, srpm | |
bdist_wininst | wininst | |
bdist_msi | msi |
Таким образом, вышеупомянутый пакет rpm может быть использован:
$ python setup.py bdist_rpm
Если вы используете bdist_wininst, распечатывается установочный файл exe, вы можете нажать для установки.
Wheel
Колесо также является встроенной упаковкой и является официально рекомендованным способом упаковки. Может быть, вы встречали или использовали упаковку для яиц, но теперь рекомендуемый метод упаковки — колесо (https://wheel.readthedocs.io/en/stable/)。
Преимущества колесного пакета:
- Faster installation for pure Python and native C extension packages.
- Avoids arbitrary code execution for installation. (Avoids setup.py)
- Installation of a C extension does not require a compiler on Windows or macOS.
- Allows better caching for testing and continuous integration.
- Creates .pyc files as part of installation to ensure they match the Python interpreter used.
- More consistent installs across platforms and machines.
Для упаковки с колесом сначала установите колесо:
$ pip install wheel
Затем используйте bdist_wheel для упаковки:
$ python setup.py bdist_wheel
После успешного выполнения, в дополнение к каталогам dist и * .egg-info, существует также каталог сборки для хранения и упаковки промежуточных данных.
Имя пакета wheel — firstApp-0.0.1-py3-none-any.whl, где py3 указывает, что поддерживается только Python3.
Можно использовать параметры —universal , Имя пакета — mfirstApp-0.0.1-py2.py3-none-any.whl, что указывает на то, что пакет wheel поддерживает как Python2, так и Python3.
Использование универсального также становится универсальным колесным пакетом, иначе его называют чистым колесным пакетом.
Установите колесо
Пример приложения в предыдущем разделе не имеет ничего. Далее добавьте модуль приветствия и переупаковки.
# greet.py def hello(): print(‘Hello, welcome to setuptools!’)
После повторной упаковки с помощью bdist_wheel, мы можем использовать pip для установки в локальный каталог сайтов-пакетов Python.
$ pip install dist/fisrtApp-0.0.1-py3-none-any.whl
Теперь он используется так же, как и другие сторонние библиотеки, установленные с помощью pip:
from myapp.greet import hello hello()
Процесс разработки приложений будет часто меняться, и сначала сложно удалить старую версию для каждой установки. При установке с использованием режима разработки, сам код будет скопирован не в пакеты сайта, а на ссылку на текущее приложение (* .egg-link). Таким образом, изменения исходного кода в текущем местоположении будут немедленно отражены в пакетах сайта. Используйте следующим образом:
$ pip install -e. # или python setup.py development
Чтобы удалить, используйте pip uninstall 。
Загрузить Колесо в PyPI
Пакет Wheel можно использовать и передавать другим людям, но его обслуживание и обновление неудобно, а PyPI в качестве репозитория программного обеспечения Python позволяет каждому легко загружать и скачивать и управлять сторонней библиотекой.
Зарегистрировать учетную запись PyPI
авторизоваться https://pypi.python.org/pypiДля входа в учетную запись.
Установить шпагат
Хотя setuptools поддерживает использование setup.py upload Загружайте файлы пакетов в PyPI, но поддерживает только HTTP и заменяет новый шпагат.
Точно так же сначала нужно установить шпагат:
$ pip install twine
Загрузить с помощью шпагата
$ twine upload dist/*
Введите имя пользователя и пароль для загрузки в PyPI. Если вы не хотите каждый раз вводить пароль учетной записи, вы можете создать файл .pypirc в домашнем каталоге следующим образом:
[distutils] index-servers = pypi pypitest [pypi] username: password: [pypitest] repository: https://test.pypi.org/legacy/ username: password:
Просто введите пароль своей учетной записи, здесь настраиваются официальные pypi и pypitest, если вы хотите настроить другие склады, добавьте в соответствии с форматом.
Вернитесь на домашнюю страницу PyPI, чтобы увидеть загруженное firstApp.
При отображении домашней страницы PyPI будет задержка, поэтому результаты не могут быть найдены сразу, и поиск в pip может оказаться невозможным, но его можно установить с помощью pip.
Выше приведено все содержимое упаковки и распространения Python, конечно же, самая простая функция. Более сложные упаковки, такие как фильтрация модулей, не-py-упаковка файлов, информация об авторах и другие общие требования, реализованы в setup() Внутри. Поэтому следующим шагом является подробное описание setup ().
параметры настройки ()
В приведенном выше установочном файле setup.py мы использовали некоторые параметры setup (): имя, версия, пакеты.
name
Имя проекта — это также имя, которое окончательно ищется в PyPI.
name = ‘firstApp’
version
Номер версии проекта, как правило, состоит из трех частей: ОСНОВНОЙ, МЕНЬШИЙ, ОБСЛУЖИВАНИЕ.
— MAJOR version when they make incompatible API changes,
— MINOR version when they add functionality in a backwards-compatible manner, and
— MAINTENANCE version when they make backwards-compatible bug fixes.
version=’0.0.1′
packages
Перечислите все пакеты, которые должны быть упакованы в проекте. Общего пользования setuptools.find_packages() Автоматическое обнаружение.
packages=find_packages(exclude=[‘contrib’, ‘docs’, ‘tests*’])
exclude Используется для исключения неупакованных пакетов.
description
Краткое описание проекта, обычно всего одно предложение, будет отображаться в нижней части имени на PyPI.
description=’My first Python project’
Для полного описания проекта используйте long_description , Если эта строка в первом формате, PyPI автоматически отобразит ее в формате HTML. Уценку также можно указать.
long_description=long_description, long_description_content_type=’text/x-rst’
url
Обычно это ссылка на GitHub или ссылка на readthedocs. ,
url=’https://github.com/pypa/sampleproject’
Источник: russianblogs.com
Выбор интерпретатора для автономных приложений Python.
Обратите внимание, что если вы указываете интерпретатор, а затем распространяете архив приложения, то необходимо убедиться, что используемый интерпретатор является переносимым. Средство запуска Python для Windows поддерживает наиболее распространенные формы POSIX строки shebang — #! , но есть и другие вопросы для рассмотрения:
- Если вы используете в исполняемом архиве строку интерпретатора /usr/bin/env python или другие формы команды python , такие как /usr/bin/python , то следует учитывать, что у пользователей по умолчанию может быть как Python 2, так и Python 3. В этом случае необходимо писать код для работы под обеими версиями.
- Если вы используете явную версию, например /usr/bin/env python3 , ваше приложение не будет работать для пользователей, у которых нет этой версии. В этом случае необходимо сделать код совместимым с Python 2.
- В исполняемом архиве невозможно указать интерпретатор как » python XY или более поздняя версия», поэтому нужно быть осторожным с использованием точной версии, например /usr/bin/env python3.7 , так как нужно будет менять строку shebang для того, чтобы запустить приложение для пользователей, у которых по умолчанию стоит Python 3.5.
Как правило, в исполняемых приложениях нужно использовать с качестве интерпретатора строку запуска /usr/bin/env python3 или /usr/bin/env python2 , в зависимости от того, написан ли ваш код для Python 3 или 2.
Напомним, что строка shebang в исполняемых архивах приложений указывается следующими способами.
Из командной строки добавить строку #! в архив с указанием интерпретатора в качестве команды для запуска:
$ python -m zipapp myapp -o myapp.pyz -p «/usr/bin/env python3» $ ./myapp.pyz
Чтобы заменить строку shebang в существующем архиве, создайте измененный архив с помощью функции zipapp.create_archive() :
>>> import zipapp >>> zipapp.create_archive(‘old_archive.pyz’, ‘new_archive.pyz’, ‘/usr/bin/python3’)
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Интерфейс командной строки модуля zipapp.
- Функции create_archive() модуля zipapp.
- Функция get_interpreter() модуля zipapp.
- Тонкости распространения исполняемых приложений Python.
- Автономное приложение на Python с помощью zipapp.
- Создание исполняемого Python файла для Windows.
Источник: docs-python.ru
Как написать, упаковать и распространить библиотеку на Python
Python — отличный язык программирования, но упаковка — одно из его самых слабых мест. Это общеизвестный факт в обществе. Установка, импорт, использование и создание пакетов значительно улучшились за эти годы, но они все еще не соответствуют новым языкам, таким как Go и Rust, которые многому научились в борьбе с Python и другими зрелыми языками.
В этом руководстве вы узнаете все, что вам нужно знать о написании, упаковке и распространении собственных пакетов.
Как написать библиотеку Python
В Python 3 есть отличный объект Path , который является огромным улучшением по сравнению с неудобным модулем os.path в Python 2. Но ему не хватает одной важной возможности — поиска пути к текущему сценарию. Это очень важно, если вы хотите найти файлы доступа относительно текущего скрипта.
Во многих случаях сценарий можно установить в любом месте, поэтому вы не можете использовать абсолютные пути, а в качестве рабочего каталога можно указать любое значение, поэтому вы не можете использовать относительный путь. Если вы хотите получить доступ к файлу в подкаталоге или родительском каталоге, вы должны иметь возможность определить текущий каталог сценария.
Вот как вы это делаете в Python:
import pathlib script_dir = pathlib.Path(__file__).parent.resolve()
Чтобы получить доступ к файлу с именем «file.txt» в подкаталоге «data» каталога текущего скрипта, вы можете использовать следующий код:
print(open(str(script_dir/’data/file.txt’).read())
В пакете pathology у вас есть встроенный метод script_dir, и вы используете его следующим образом:
from pathology.Path import script_dir print(open(str(script_dir()/’data/file.txt’).read())
Да, это полный рот. Пакет патологии очень прост. Он наследует свой собственный класс Path от Pathlib библиотеки path и добавляет статический script_dir(), который всегда возвращает путь вызывающего скрипта.
Из-за кросс-платформенной реализации pathlib.Path вы можете наследовать непосредственно от него и должны наследовать от определенного подкласса ( PosixPath или WindowsPath ). Разрешение script_dir использует модуль проверки, чтобы найти вызывающую программу, а затем ее атрибут имени файла.
Более 2 миллионов тем и плагинов WordPress, веб-шаблонов и шаблонов электронной почты, наборов пользовательского интерфейса и многого другого
Загрузите тысячи тем и плагинов WordPress, веб-шаблонов, элементов пользовательского интерфейса и многое другое с членством в Envato Elements. Получите неограниченный доступ к растущей библиотеке из миллионов творческих и кодовых ресурсов.
Тестирование пакета патологии
import os import shutil from unittest import TestCase from pathology.path import Path class PathTest(TestCase): def test_script_dir(self): expected = os.path.abspath(os.path.dirname(__file__)) actual = str(Path.script_dir()) self.assertEqual(expected, actual) def test_file_access(self): script_dir = os.path.abspath(os.path.dirname(__file__)) subdir = os.path.join(script_dir, ‘test_data’) if Path(subdir).is_dir(): shutil.rmtree(subdir) os.makedirs(subdir) file_path = str(Path(subdir)/’file.txt’) content = ‘123’ open(file_path, ‘w’).write(content) test_path = Path.script_dir()/subdir/’file.txt’ actual = open(str(test_path)).read() self.assertEqual(content, actual)
Путь Python
Пакеты Python должны быть установлены где-то на пути поиска Python, чтобы их можно было импортировать модулями Python. Путь поиска Python представляет собой список каталогов и всегда доступен в sys.path . Вот мой текущий sys.path :
>>> print(‘n’.join(sys.path)) /Users/gigi.sayfan/miniconda3/envs/py3/lib/python36.zip /Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6 /Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6/lib-dynload /Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6/site-packages /Users/gigi.sayfan/miniconda3/envs/py3/lib/python3.6/site-packages/setuptools-27.2.0-py3.6.egg
Обратите внимание, что первая пустая строка вывода представляет текущий каталог, поэтому вы можете импортировать модули из текущего рабочего каталога, каким бы он ни был. Вы можете напрямую добавлять или удалять каталоги в/из sys.path.
Вы также можете определить переменную среды PYTHONPATH и несколько других способов управления ею. Стандартные site-packages включены по умолчанию, и именно сюда идут пакеты, которые вы устанавливаете с помощью pip.
Как упаковать библиотеку Python
Теперь, когда у нас есть код и тесты, давайте упакуем их в соответствующую библиотеку. Python предоставляет простой способ через модуль установки. Вы создаете файл с именем setup.py в корневом каталоге вашего пакета.
Файлы setup.py содержат множество метаданных, таких как автор, лицензия, сопровождающие и другую информацию о пакете. Это в дополнение к элементу пакетов ( packages ), который использует функцию find_packages() , импортированную из setuptools , для поиска подпакетов.
Вот файл setup.py пакета патологии:
Исходный дистрибутив
Пакет исходного дистрибутива — это архивный файл, содержащий пакеты Python, модули, а также другие файлы, которые используются для выпуска пакета (например, версии 1, 2 и т. д.). После распространения файла конечные пользователи могут загрузить и установить его в своей операционной системе.
Чтобы создать исходный дистрибутив (sdist), запустите: python setup.py sdist
Давайте создадим исходный дистрибутив:
$ python setup.py sdist running sdist running egg_info creating pathology.egg-info writing pathology.egg-info/PKG-INFO writing dependency_links to pathology.egg-info/dependency_links.txt writing top-level names to pathology.egg-info/top_level.txt writing manifest file ‘pathology.egg-info/SOURCES.txt’ reading manifest file ‘pathology.egg-info/SOURCES.txt’ writing manifest file ‘pathology.egg-info/SOURCES.txt’ warning: sdist: standard file not found: should have one of README, README.rst, README.txt running check creating pathology-0.1 creating pathology-0.1/pathology creating pathology-0.1/pathology.egg-info copying files to pathology-0.1. copying setup.py -> pathology-0.1 copying pathology/__init__.py -> pathology-0.1/pathology copying pathology/path.py -> pathology-0.1/pathology copying pathology.egg-info/PKG-INFO -> pathology-0.1/pathology.egg-info copying pathology.egg-info/SOURCES.txt -> pathology-0.1/pathology.egg-info copying pathology.egg-info/dependency_links.txt -> pathology-0.1/pathology.egg-info copying pathology.egg-info/not-zip-safe -> pathology-0.1/pathology.egg-info copying pathology.egg-info/top_level.txt -> pathology-0.1/pathology.egg-info Writing pathology-0.1/setup.cfg creating dist Creating tar archive removing ‘pathology-0.1’ (and everything under it)
Предупреждение связано с тем, что я использовал нестандартный файл README.md. Безопасно игнорировать. Приведенная выше команда создаст файл архива в формате по умолчанию для текущей операционной системы. Для систем Unix будет сгенерирован сжатый tar-файл в каталоге dist:
$ ls -la dist total 8 drwxr-xr-x 3 gigi.sayfan gigi.sayfan 102 Apr 18 21:20 . drwxr-xr-x 12 gigi.sayfan gigi.sayfan 408 Apr 18 21:20 .. -rw-r—r— 1 gigi.sayfan gigi.sayfan 1223 Apr 18 21:20 pathology-0.1.tar.gz
Если вы используете Windows, создается zip-файл.
Вы также можете указать другие дополнительные форматы файлов, используя параметр формата, как показано ниже.
python setup.py sdist —formats=gztar,zip
Например, приведенная выше команда создаст tar-архив, сжатый gzip, и zip-файл.
Доступны следующие форматы:
Бинарное распространение
Чтобы создать двоичный дистрибутив, называемый колесом, запустите: python setup.py bdist_wheel
$ python setup.py bdist_wheel running bdist_wheel running build running build_py creating build creating build/lib creating build/lib/pathology copying pathology/__init__.py -> build/lib/pathology copying pathology/path.py -> build/lib/pathology installing to build/bdist.macosx-10.7-x86_64/wheel running install running install_lib creating build/bdist.macosx-10.7-x86_64 creating build/bdist.macosx-10.7-x86_64/wheel creating build/bdist.macosx-10.7-x86_64/wheel/pathology copying build/lib/pathology/__init__.py -> build/bdist.macosx-10.7-x86_64/wheel/pathology copying build/lib/pathology/path.py -> build/bdist.macosx-10.7-x86_64/wheel/pathology running install_egg_info running egg_info writing pathology.egg-info/PKG-INFO writing dependency_links to pathology.egg-info/dependency_links.txt writing top-level names to pathology.egg-info/top_level.txt reading manifest file ‘pathology.egg-info/SOURCES.txt’ writing manifest file ‘pathology.egg-info/SOURCES.txt’ Copying pathology.egg-info to build/bdist.macosx-10.7-x86_64/wheel/pathology-0.1-py3.6.egg-info running install_scripts creating build/bdist.macosx-10.7-x86_64/wheel/pathology-0.1.dist-info/WHEEL
Пакет патологии содержит только чистые модули Python, поэтому можно создать универсальный пакет. Если ваш пакет включает расширения C, вам придется создать отдельное колесо для каждой платформы:Пакет патологии содержит только чистые модули Python, поэтому можно создать универсальный пакет. Если ваш пакет включает расширения C, вам придется создать отдельное колесо для каждой платформы:
$ ls -la dist total 16 drwxr-xr-x 4 gigi.sayfan gigi.sayfan 136 Apr 18 21:24 . drwxr-xr-x 13 gigi.sayfan gigi.sayfan 442 Apr 18 21:24 .. -rw-r—r— 1 gigi.sayfan gigi.sayfan 2695 Apr 18 21:24 pathology-0.1-py3-none-any.whl -rw-r—r— 1 gigi.sayfan gigi.sayfan 1223 Apr 18 21:20 pathology-0.1.tar.gz
Чтобы глубже погрузиться в тему упаковки библиотек Python, можно ознакомиться информацией как писать собственные пакеты Python.
Как распространять пакет Python
Python имеет центральный репозиторий пакетов под названием PyPI (Python Packages Index). PyPI упрощает управление различными версиями пакетов. Например, если пользователю нужно установить определенную версию пакета, pip знает, где ее искать.
Когда вы устанавливаете пакет Python с помощью pip, он загружает пакет из PyPI (если вы не укажете другой репозиторий). Чтобы распространить наш пакет патологии, нам нужно загрузить его в PyPI и предоставить некоторые дополнительные метаданные, которые требуются PyPI. Шаги:
- Обновите версию вашего пипса.
- Создайте учетную запись на PyPI (только один раз).
- Зарегистрируйте свой пакет.
- Загрузите свой пакет.
Обновите версию вашего pip
Убедитесь, что в вашей операционной системе установлена последняя версия pip. Чтобы обновить pip, введите следующую команду
python3 -m pip install —upgrade pip
Завести аккаунт
Вы можете создать учетную запись на веб-сайте PyPI. Затем создайте файл .pypirc в своем домашнем каталоге:
[distutils] index-servers=pypi [pypi] repository = https://pypi.python.org/pypi username = the_gigi
В целях тестирования вы можете добавить индексный сервер pypitest в свой файл .pypirc:
[distutils] index-servers= pypi pypitest [pypitest] repository = https://testpypi.python.org/pypi username = the_gigi [pypi] repository = https://pypi.python.org/pypi username = the_gigi
Зарегистрируйте свой пакет
Если это первый выпуск вашего пакета, вам необходимо зарегистрировать его в PyPI. Используйте команду регистрации файла setup.py. Он попросит вас ввести пароль. Обратите внимание, что я указываю на тестовый репозиторий здесь:
$ python setup.py register -r pypitest running register running egg_info writing pathology.egg-info/PKG-INFO writing dependency_links to pathology.egg-info/dependency_links.txt writing top-level names to pathology.egg-info/top_level.txt reading manifest file ‘pathology.egg-info/SOURCES.txt’ writing manifest file ‘pathology.egg-info/SOURCES.txt’ running check Password: Registering pathology to https://testpypi.python.org/pypi Server response (200): OK
Загрузите свой пакет
Теперь, когда пакет зарегистрирован, мы можем его загрузить. Я рекомендую использовать twine, который более надежен. Установите его как обычно, используя pip install twine . Затем загрузите свой пакет с помощью twine и укажите свой пароль (отредактировано ниже):
$ twine upload -r pypitest -p dist/* Uploading distributions to https://testpypi.python.org/pypi Uploading pathology-0.1-py3-none-any.whl [================================] 5679/5679 — 00:00:02 Uploading pathology-0.1.tar.gz [================================] 4185/4185 — 00:00:01
Пакет теперь доступен на официальном сайте Pypi, как показано ниже.
Чтобы установить его с помощью pip, просто введите следующую команду:
pip install pathology
Чтобы глубже погрузиться в тему распространения ваших пакетов, необходимо ознакомьться с информацией как поделиться своими пакетами Python.
Вывод
В этом руководстве мы прошли полноценный процесс написания библиотеки Python, ее упаковки и распространения через PyPI. К этому моменту у вас уже должны быть все инструменты для создания библиотек и обмена ими со всем миром.
Источник: dev-gang.ru