Подтвердить что ты не робот

Простой пакет Hello World setuptools и установка его с помощью pip

Мне сложно понять, как установить мой пакет с помощью setuptools, и я пробовал читать документацию на нем и сообщениях SO, но я не могу заставить его работать правильно. Я пытаюсь получить простое приложение helloworld для работы. Вот как я догадался:

helloworld.py:

print("Hello, World!")

README.txt:

Hello, World! readme

MANIFEST.in:

recursive-include images *.gif

setup.py:

from setuptools import setup, find_packages

setup(
    name='helloworld',
    version='0.1',
    license='BSD',
    author='gyeh',
    author_email='[email protected]',
    url='http://www.hello.com',
    long_description="README.txt",
    packages=find_packages(),
    scripts = ['helloworld.py'],
    package_data={
        "" : ["images/*.gif"]
    },
    data_files=[('images', ['images/hello.gif'])],
    description="Hello World testing setuptools",
)

И у меня есть пустой файл с именем images/hello.gif, который я хочу включить в свой пакет в качестве дополнительных данных. Структура папок выглядит следующим образом:

testsetup/  
|-- helloworld.py  
|-- images/  
|-- --- hello.gif  
|-- MANIFEST.in  
|-- README.txt  
|-- setup.py  

Когда я запускаю python setup.py sdist, он успешно создает dist и helloworld.egg-info. Когда я смотрю на файл SOURCES.txt под информацией о яйце, он содержит script и изображение под папкой изображений, а также tarball под dist содержит их.

Однако, когда я пытаюсь запустить pip install --user helloworld-0.1.tar.gz в tarball, он успешно устанавливает его, но я не могу найти программные файлы helloworld.py и images/hello.gif.

Когда я смотрю под $HOME/.local/lib/python3.3/site-packages/, я вижу папку с информацией о яйце и все содержимое, установленное там. Но папка $HOME/.local/bin даже не существует. Хранили ли файлы программ в другом месте? Что я здесь делаю неправильно? Я запускаю Arch Linux.

4b9b3361

Ответ 1

Хорошо, поэтому, после некоторого усилия, мне наконец-то удалось получить простой "привет мир" пример для setuptools. Документация на Python обычно потрясающая, но я хочу, чтобы документация была лучше в этом, в частности.

Я собираюсь написать довольно подробное руководство о том, как я это достиг, и я не буду предполагать, что у читателя по этому вопросу нет предварительной информации. Надеюсь, это пригодится другим...

Чтобы настроить этот пример, мы создадим пакет (фактически два из них, один для файлов данных). Это структура каталогов, в которой мы закончим:

test-setuptools/
|-- helloworld/
|-- --- hello.py
|-- --- images/
|-- --- --- hello.gif
|-- --- --- __init__.py
|-- --- __init__.py
|-- MANIFEST.in
|-- README.txt
|-- setup.py

Вот шаги:

  • Создайте пакет helloworld.
    1.1 Создайте папку helloworld/, как показано в структуре каталогов выше.

    1.2 Добавьте пустой файл с именем __init__.py в папку helloworld/.
    Если вы его не добавите, пакет не будет распознан (запустите touch __init__.py, чтобы создать файл на машинах linux/mac). Если вы хотите, чтобы какой-либо код выполнялся каждый раз при импорте пакета, включите его в файл __init__.py.

    1.3 Создайте файл hello.py script, чтобы продемонстрировать функциональность пакета.

Вот код для hello.py:

import os

"""
Open additional data files using the absolute path,
otherwise it doesn't always find the file.
"""
# The absolute path of the directoy for this file:
_ROOT = os.path.abspath(os.path.dirname(__file__))

class Hello(object):
    def say_hello(self):
        return "Hello, World!"
    def open_image(self):
        print("Reading image.gif contents:")

        # Get the absolute path of the image relative path:
        absolute_image_path = os.path.join(_ROOT, 'images/hello.gif')

        with open(absolute_image_path, "r") as f:
            for line in f:
                print(line)
  • 1.4 Создайте папку images/ внутри папки helloworld/.
    Сделайте еще один пустой файл __init__.py, потому что эта папка также будет пакетом.

    1.5 Создайте файл hello.gif внутри папки images/.
    Этот файл не будет фактическим gif файлом. Вместо этого добавьте простой текст, чтобы продемонстрировать, что файлы без script могут быть добавлены и прочитаны.

Я добавил следующий код в hello.gif:

This should be the data inside hello.gif...
...but this is just to demonstrate setuptools,
so it a dummy gif containing plain text
  • 1.6 Проверьте свой пакет
    Запустите python из папки test-setuptools, которая откроет интерпретатор python.
    Введите import helloworld.hello, чтобы импортировать hello.py script в пакет helloworld. Импорт должен быть успешным, указывая, что вы успешно создали пакет. Убедитесь, что пакет в папке images/ также работает, набрав import helloworld.images
    Попробуйте создать экземпляр объекта, который мы написали в hello.py. Введите следующие команды, чтобы убедиться, что все работает так, как ожидалось:
    hey = helloworld.hello.Hello()
    hey.say_hello()
    hey.open_image()

  • Создайте файл setup.py и остальные файлы.
    2.1 Создайте простой файл README.txt. Мой имеет только текст: Hello, World! Readme внутри.

    2.2 Создайте файл MANIFEST.in со следующим содержимым:
    include helloworld/images/hello.gif
    .
    Это очень важно важно, потому что он сообщает setuptools включать дополнительные данные в исходный дистрибутив (который мы сгенерируем на более позднем этапе). Без этого вы не сможете установить дополнительные, не .py данные в свой пакет. Подробнее см. .

    2.3 Создайте файл setup.py (см. код ниже).
    Наиболее важными атрибутами являются packages, include_package_data и package_data.
    .
    Атрибут packages содержит список пакетов, которые вы хотите включить для setuptools. Мы хотим включить пакет helloworld и пакет helloworld.images, содержащий наши дополнительные данные hello.gif.
    Вы можете заставить setuptools автоматически найти их, добавив from setuptools import find_packages импорт и запуск импортированной функции find_packages(). Запустите интерпретатор из папки test-setuptools и проверьте эту команду, чтобы узнать, какие пакеты найдены.
    .
    Атрибут package_data сообщает setuptools включать дополнительные данные. Это эта команда, пакет helloworld.images и файл MANIFEST.in, которые позволяют устанавливать дополнительные данные.
    Пара ключей/значений 'helloworld.images' : ['hello.gif'] сообщает setuptools включать hello.gif в пакет helloworld.images, если он существует. Вы также можете сказать '' : ['*.gif'], чтобы включить любой .gif файл в любой из включенных пакетов.
    Для этого необходим атрибут include_package_data, установленный на True.
    Вы можете включить дополнительные метаданные для пакета, как у меня (я думаю, нужен author). Это хорошая идея добавить классификаторы. Дополнительную информацию можно найти здесь.

Вот весь код setup.py:

from setuptools import setup

setup(
    name='helloworld',
    version='0.1',
    license='BSD',
    author='gyeh',
    author_email='[email protected]',
    url='http://www.hello.com',
    long_description="README.txt",
    packages=['helloworld', 'helloworld.images'],
    include_package_data=True,
    package_data={'helloworld.images' : ['hello.gif']},
    description="Hello World testing setuptools",
)

.
3. Установите и протестируйте свой пакет с помощью setuptools.

3.1 Create the source distribution  

Запустите python setup.py sdist из папки test-setuptools/, чтобы создать исходный дистрибутив.
Это создаст папку dist/, содержащую ваш пакет, и папку helloworld.egg-info/, содержащую метаданные, такие как SOURCE.txt.
Проверьте SOURCE.txt, чтобы увидеть, включен ли в него файл изображения hello.gif.
Откройте файл .tar.gz в папке dist/. Вы должны увидеть все файлы, описанные в ранее созданной структуре каталогов, включая hello.gif и hello.py.

3.2 Install the distribution  

Установите файл распространения .tar.gz, запустив pip install --user helloworld-0.1.tar.gz из папки dist/.
Убедитесь, что пакет был успешно установлен, запустив pip list. Пакет helloworld должен быть там.

Что это! теперь вы сможете проверить свой пакет под любой папкой. Откройте интерпретатор в любой папке, кроме test-setuptools, и попробуйте импортировать пакет с помощью import helloworld.hello. Он должен работать. Затем попробуйте команды для создания экземпляра объекта и снова откройте файл изображения с помощью команды hey.open_image(). Он все равно должен работать!

Вы можете точно определить, какие файлы были установлены в pip, и где они находятся, путем удаления пакета. Мой выглядел так:

[[email protected] package]$ pip uninstall helloworld
Uninstalling helloworld:
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld-0.1-py3.3.egg-info
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/__init__.py
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/__pycache__/__init__.cpython-33.pyc
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/__pycache__/hello.cpython-33.pyc
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/hello.py
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/images/__init__.py
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/images/__pycache__/__init__.cpython-33.pyc
  /home/gyeh/.local/lib/python3.3/site-packages/helloworld/images/hello.gif
Proceed (y/n)? y
  Successfully uninstalled helloworld

Как вы можете видеть, он успешно установил дополнительный файл данных hello.gif, и поскольку мы преобразовали относительный путь к абсолютному пути в hello.py, он может отлично прочитать файл.
Затем вы можете поделиться этим пакетом на PyPI для остального мира! Инструкции по загрузке в PyPI довольно просты и здесь можно найти здесь и здесь.

Как только он будет доступен в PyPI, люди смогут выполнить поиск вашего пакета с помощью pip search. Или, наоборот, при запуске pip install --user [package-name] будет указывать pip для поиска в онлайн-директории PyPI для этого имени пакета. Если он существует, он установит его.

Вы можете запустить эту команду для любого пакета python, который в PyPI для простой установки, чтобы вы не обманывали файлы сборки.

Надеюсь, это избавит людей от кучи головных болей.