При создании сценария командной строки, рекомендуется писать их как модули, которые будут распространяются с помощью setuptools
, вместо использования директивы Unix shebangs (#!/usr/bin/python3
).
Причины, по которым следует интегрировать сценарий CLI, написанные на click
с возможностями setuptools
:
Не все платформы поддерживают выполнение скриптов, как самостоятельно исполняемых файлов. В Linux и OS X можно добавить комментарий в начало файла #!/usr/bin/env python3
, и он будет работать как исполняемый файл, при условии, что у него установлен исполняемый бит. Но в Windows это работать НЕ БУДЕТ. В Windows можно связать интерпретатор с расширениями файлов (например, все, что заканчивается на .py
, выполняется через интерпретатор Python), и все равно будут проблемы с запуском в virtualenv
.
Запуск сценария в виртуальном окружении на системах OS X и Linux также является проблемой. При традиционном подходе, необходимо активировать virtualenv
, что не очень удобно.
Трюк с __main__
в коде сценария работает только в том случае, если скрипт является модулем Python. Если приложение из модуля переросло в пакет то при запуске возникнут проблемы.
Если созданный сценарий командной строки имеет зависимости от сторонних модулей, то перенос его на другую систему/платформу становиться проблемой. Пакет 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 растет, обрастает дополнительными модулями и утилитами, то рано или поздно встает необходимость переключиться на запуск скрипта, который содержится в пакете создаваемого сценария. В этом случае, при использовании 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', ], }, )