将Python3脚本作为CLI

时间:2018-11-29 10:36:22

标签: python python-3.x pip command-line-interface

我有一个具有以下结构的python3脚本。我希望通过pip将这些代码作为CLI实用程序(而不是python3模块)提供。它不是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-Packaging Tutorial,它确实提到了python模块的CLI

当前目录结构

.
|-- 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 :(得分:0)

  

这时我不确定应该在bin /偏转文件中写什么?

什么都没有。您不应该将可执行文件发送到源代码树的bin文件夹中。可执行文件将在安装时创建。

我建议您使用flitpyproject.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'

然后使用flit publish将代码上传到PyPI。

答案 1 :(得分:0)

@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()

当我在仓库中使用virtualenvpip install .中进行检查,并在$ deflection中检查它是否运行时,一切都很好