Сообщить об ошибке.

Интеграция модуля click с setuptools в Python

При создании сценария командной строки, рекомендуется писать их как модули, которые будут распространяются с помощью setuptools, вместо использования директивы Unix shebangs (#!/usr/bin/python3).

Причины, по которым следует интегрировать сценарий CLI, написанные на click с возможностями setuptools:

  1. Не все платформы поддерживают выполнение скриптов, как самостоятельно исполняемых файлов. В Linux и OS X можно добавить комментарий в начало файла #!/usr/bin/env python3, и он будет работать как исполняемый файл, при условии, что у него установлен исполняемый бит. Но в Windows это работать НЕ БУДЕТ. В Windows можно связать интерпретатор с расширениями файлов (например, все, что заканчивается на .py, выполняется через интерпретатор Python), и все равно будут проблемы с запуском в virtualenv.

  2. Запуск сценария в виртуальном окружении на системах OS X и Linux также является проблемой. При традиционном подходе, необходимо активировать virtualenv, что не очень удобно.

  3. Трюк с __main__ в коде сценария работает только в том случае, если скрипт является модулем Python. Если приложение из модуля переросло в пакет то при запуске возникнут проблемы.

  4. Если созданный сценарий командной строки имеет зависимости от сторонних модулей, то перенос его на другую систему/платформу становиться проблемой. Пакет setuptools создан для того, чтобы более легко создавать и распространять пакеты Python, особенно те, которые имеют зависимости от сторонних модулей/пакетов.

Базовая концепция использования модуля click с setuptools.

Чтобы связать сценарий командной строки click с setuptools, понадобится только сам скрипт и файл setup.py.

Допустим, что сценарий yourscript.py и созданный setup.py лежат в корне диска:

yourscript.py
setup.py

Содержимое скрипта yourscript.py:

import click

@click.command()
def cli():
    """Example script."""
    click.echo('Hello World!')

Содержимое setup.py:

from setuptools import setup

setup(
    name='yourscript',
    version='0.1.0',
    py_modules=['yourscript'],
    install_requires=[
        'Click',
    ],
    entry_points={
        'console_scripts': [
            'yourscript = yourscript:cli',
        ],
    },
)

Магия заключается в параметре entry_points. Каждая строка ниже console_scripts определяет один консольный скрипт. Первая часть перед знаком равенства = - это имя сценария, который необходимо сгенерировать, вторая часть - это путь импорта, за которым следует двоеточие : с командой модуля click.

Вот и все.

Тестирование сценария

Чтобы протестировать сценарий CLI, можно создать новый virtualenv, а затем установить свой пакет:

$ virtualenv venv
$ . venv/bin/activate
$ pip install --editable .

После этого, сценарий CLI должен быть доступен как:

$ yourscript
# Hello World!

То есть как системная утилита, без расширения .py

Сценарии CLI в пакетах Python.

Если сценарий CLI растет, обрастает дополнительными модулями и утилитами, то рано или поздно встает необходимость переключиться на запуск скрипта, который содержится в пакете создаваемого сценария. В этом случае, при использовании setuptools, необходимые изменения будут минимальны.

Предположим, что структура каталогов изменилась:

project/
    yourpackage/
        __init__.py
        main.py
        utils.py
        scripts/
            __init__.py
            yourscript.py
    setup.py

В этом случае вместо использования py_modules в файле setup.py можно использовать пакеты и поддержку автоматического поиска пакетов с помощью setuptools. В дополнение к этому также рекомендуется включать другие данные о пакете.

Содержимое setup.py будет изменено :

from setuptools import setup, find_packages

setup(
    name='yourpackage',
    version='0.1.0',
    packages=find_packages(),
    include_package_data=True,
    install_requires=[
        'Click',
    ],
    entry_points={
        'console_scripts': [
            'yourscript = yourpackage.scripts.yourscript:cli',
        ],
    },
)