сделать скрипт Python3 как CLI - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть один скрипт Python3, который имеет следующую структуру.Я хочу сделать этот код доступным как утилита CLI (а не модуль python3) через pip.Причина, по которой он не является модулем python3, заключается в том, что логика очень прямолинейна, и я не вижу смысла в том, чтобы преобразовать код в меньшие файлы python, чтобы сделать его модулем.

Код deflection.py

def func1():
 """some useful function here"""


def main(args):
""" My MAIN Logic here!!"""


def parse_args():
"""Parse Arguments if Passed else use configuration file"""

    parser = argparse.ArgumentParser(description='what the CLI should do.')


    parser.add_argument('--ip', type=str, required=False, help='descp@1')
    # Add more arguments (trimmed for code brevity)

    return parser.parse_args()


if __name__ == '__main__':
    args = parse_args()
    CONF = dict() # create a dict for reading a `conf.json` file from `/etc/` folder

    with open(CONF_PATH) as cFile:
        _conf = json.load(cFile)
        CONF = _conf['Key_Of_Interest']

   # Check Argument conditions
    if condition_1:
        print('Starting Script in Default Mode. Reading Conf File conf.json')
        try:
            main(...) # pass all the default args here

        except KeyboardInterrupt as e:
            # if CTRL C pressed safe exit
            sys.exit(0)

    elif condition_2:
        # if one particular argument wasn't mentioned, stop script
        sys.exit(1)
    else:
        print('Starting Script with Custom Arguments.')
        try:
            main(..) # custom args to main function

        except KeyboardInterrupt as e:
            # safe exit if CTRL C pressed
            sys.exit(0)

Я следую Python-пакету учебника , в котором упоминается CLI для модулей Python.

Текущая структура каталогов

.
|-- bin
|   `-- deflection
|-- deflection
|   |-- deflection.py
|   `-- __init__.py
|-- MANIFEST.in
|-- README.rst
`-- setup.py

setup.py

from setuptools import setup

def readme():
    with open('README.rst') as f:
        return f.read()

setup(name='deflection',
      version='0.1',
      description='Extract Micro-Epsilon OptoNCDT values and store into InfluxDB',
      long_description=readme(),
      url='https://mypersonalgitlabLink.com/awesomeCLIProject',
      author='Monty Python',
      author_email='Monty@python.org',
      license='GPLv3',
      packages=['deflection'],
      scripts=['bin/deflection']
      install_requires=[
            'influxdb-python'
      ],
      zip_safe=False)

На данный момент я не уверен, что должно быть записано в bin/deflection файле?

#!/usr/bin/env python3
from .deflection import main # NOT SURE Here! because main() requires arguments

Я могу просто выбрать chmod +x deflection.py, но у меня есть зависимость influxdb-pythonкоторый я хочу отправить через pip, т.е. когда кто-то делает

`pip3 install deflection`

, пользователи могут напрямую сделать $ deflection --arg1='test' и использовать скрипт.

Как мне добиться этого без использования click или любые другие вспомогательные модули и придерживаться ядра pip?

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

как упомянуто @schlamar в разделе комментариев:

Я добавил весь код в блоке __name__=='__main__' в отдельную функцию с именем main() и переименовал функцию main(args) в send_data(args).

def send_data(args):
  """ refactor the function name"""

def main():
    args = parse_args()
    CONF = dict() # create a dict for reading a `conf.json` file from `/etc/` folder

    with open(CONF_PATH) as cFile:
        _conf = json.load(cFile)
        CONF = _conf['Key_Of_Interest']

   # Check Argument conditions
    if condition_1:
        print('Starting Script in Default Mode. Reading Conf File conf.json')
        try:
            send_data(...) # pass all the default args here

        except KeyboardInterrupt as e:
            # if CTRL C pressed safe exit
            sys.exit(0)

    elif condition_2:
        # if one particular argument wasn't mentioned, stop script
        sys.exit(1)
    else:
        print('Starting Script with Custom Arguments.')
        try:
            send_data(..) # custom args to main function

        except KeyboardInterrupt as e:
            # safe exit if CTRL C pressed
            sys.exit(0)

в моем bin/deflection Я добавил

#!/usr/bin/env python3

import deflection

if __name__ == '__main__':
   deflection.main()

Теперь все работает хорошо, когда я проверил это в virtualenv, используя pip install . в репо и $ deflection, чтобы проверитьесли он работает

0 голосов
/ 29 ноября 2018

На данный момент я не уверен, что следует записать в файл bin / deflection?

Ничего.Вы не должны отправлять исполняемый файл в папку bin вашего исходного дерева.Исполняемый файл будет создан после установки.

Я предлагаю вам использовать flit и pyproject.toml.Это значительно упростит ваш проект.Сначала добавьте файл pyproject.toml (вместо setup.py):

[build-system]
requires = ['flit']
build-backend = 'flit.buildapi'

[tool.flit.metadata]
module = 'deflection'
requires-python = '>=3'
description-file = 'README.rst'
requires = ['influxdb-python']

[tool.flit.scripts]
deflection = 'deflection.deflection:main'

Затем загрузите свой код в PyPI с помощью flit publish.

...