我有一个具有以下结构的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
来实现这一目标?
答案 0 :(得分:0)
这时我不确定应该在bin /偏转文件中写什么?
什么都没有。您不应该将可执行文件发送到源代码树的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'
然后使用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()
当我在仓库中使用virtualenv
在pip install .
中进行检查,并在$ deflection
中检查它是否运行时,一切都很好