简体   繁体   English

如何在 Python 中创建可以与 PIP 一起安装的 CLI?

[英]How to create a CLI in Python that can be installed with PIP?

As the title suggests, I'm trying to make a python script accessible from the command line.正如标题所示,我正在尝试使 python 脚本可以从命令行访问。 I've found libraries like click and argv that make it easy to access arguments passed from the command line, but the user still has to run the script through Python.我发现像clickargv这样的库可以轻松访问从命令行传递的 arguments,但用户仍然必须通过 Python 运行脚本。

Instead of代替

python /location/to/myscript.py

I want to be able to just do我希望能够做到

myscript

from any directory从任何目录

From what I understand, I can achieve this on my computer by editing my PATH variables.据我了解,我可以通过编辑我的 PATH 变量在我的计算机上实现这一点。 However, I would like to be able to simply do:但是,我希望能够简单地做:

pip install myscript

and then access the script by typing myscript from anywhere.然后通过从任何地方键入myscript来访问脚本。 Is there some special code I would put in the setup.py ?我会在setup.py中放入一些特殊代码吗?

You can do this with setuptools您可以使用setuptools执行此setuptools

an example of a nice setup.py (say your package requires pandas and numpy):一个不错的setup.py示例(假设您的包需要 pandas 和 numpy):

import setuptools
setuptools.setup(
    name='myscript',
    version='1.0',
    scripts=['./scripts/myscript'],
    author='Me',
    description='This runs my script which is great.',
    packages=['lib.myscript']
    install_requires=[
        'setuptools',
        'pandas >= 0.22.0',
        'numpy >= 1.16.0'
    ],
    python_requires='>=3.5'
)

Your directory should be setup as follows:您的目录应设置如下:

[dkennetz package]$ ls
lib scripts setup.py

inside lib would be:里面的 lib 将是:

[dkennetz package]$ ls lib
myscript

inside of myscript would be: myscript内部将是:

[dkennetz package]$ ls lib/myscript
__main__.py
__init__.py
helper_module1.py
helper_module2.py

main would be used to call your function and do whatever you want to do. main 将用于调用您的函数并执行您想做的任何操作。

inside scripts would be:内部脚本将是:

[dkennetz package]$ ls scripts
myscript

and the contents of myscript would be: myscript的内容是:

#!/usr/bin/env bash

if [[ ! $@ ]]; then
    python3 -m myscript -h
else
    python3 -m myscript $@
fi

then to run you do: python setup.py install然后运行你做: python setup.py install

which will install your program and all of the dependencies you included in install_requires=[] in your setup.py and install myscript as a command-line module:这将安装您的程序以及您在 setup.py 中的install_requires=[]中包含的所有依赖项,并将myscript作为命令行模块安装:

[dkennetz ~]$ myscript

Use console_scripts to hook to a specific Python method (not calling whole executable), setup.py file:使用console_scripts挂钩到特定的 Python 方法(不调用整个可执行文件), setup.py文件:

from setuptools import setup
setup(
    ...
    entry_points = {
        'console_scripts': ['mybinary=mymodule.command_line:cli'],
    },
    name='mymodule',
    ...
)

the command_line.py script would be: command_line.py脚本将是:

import mymodule

def cli():
    print("Hello world!")

and the project directory would look like this:项目目录如下所示:

myproject/
    mymodule/
        __init__.py
        command_line.py
        ...
    setup.py

See packaging documentation for more details . 有关详细信息,请参阅包装文档

Assuming you are in the bash shell and python 3 is installed and you want to be able to do what you are requesting, you will need to append the path of the script file to your PATH variable in your .bash_profile file in your home directory.假设您在 bash shell 中并且安装了 python 3 并且您希望能够执行您的请求,您需要将脚本文件的路径附加到您的主目录中的.bash_profile文件中的 PATH 变量。 Also, in your python script file, you need to have something similar to the following as the first line of the script:此外,在您的 python 脚本文件中,您需要将类似于以下内容的内容作为脚本的第一行:

#!/usr/bin/env python3

Additionally, you can remove the extension (.py) from the script file, such that, as in my example above, the filename is a script in contrast to script.py.此外,您可以从脚本文件中删除扩展名 (.py),例如,在我上面的示例中,与 script.py 相比,文件名是一个脚本。

You will also need to set the permission of your filename to您还需要将文件名的权限设置为

chmod 755 filename chmod 755 文件名

If you want the script to be accessible system-wide, you will need to modify /etc/profile and add to the bottom of the file:如果您希望脚本可在系统范围内访问,则需要修改 /etc/profile 并添加到文件底部:

export PATH=$PATH:/path/to/script

Alternatively, if you move the python script file to /usr/local/bin , it may not be necessary to make any profile changes as this directory is often already in the PATH.或者,如果您将 python 脚本文件移动到/usr/local/bin ,则可能不需要进行任何配置文件更改,因为该目录通常已在 PATH 中。

To see the value of PATH issue the following command at the shell要查看 PATH 的值,请在 shell 中发出以下命令

echo $PATH

I know this question is older and for a project using setuptools definitely use Tombart's answer我知道这个问题比较老,对于使用setuptools的项目,肯定会使用Tombart 的答案

That said, I have been using poetry and that uses a .toml file and if that's what you use, and since this is likely what others will search for here's how you package a script with a toml file ( at least with poetry )也就是说,我一直在使用诗歌,并且使用.toml文件,如果这就是你使用的,因为这可能是其他人会搜索的内容,这就是你如何 package 一个带有 toml 文件的脚本(至少带有诗歌

[project.scripts]
myscript = "mybinary=mymodule.command_line:cli"

Not sure if this works for flit or any other package managers but it works for poetry不确定这是否适用于 flit 或任何其他 package 经理,但它适用于诗歌

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM