【问题标题】:Package a command line application for distribution?打包一个命令行应用程序进行分发?
【发布时间】:2014-07-31 08:37:40
【问题描述】:

我目前正在用 Python 编写一个命令行应用程序,它需要以易于下载和运行的方式提供给最终用户。对于那些在 Windows 上可能没有安装 Python (2.7) 的人,我打算使用PyInstaller 来生成一个独立的 Windows 可执行文件。然后,用户将能够简单地下载“myapp.exe”并运行myapp.exe [ARGUMENTS]

我还想为已经安装了 Python 的用户(在各种平台上)提供一个(较小的)下载。一种选择是将我的所有代码放入一个 .py 文件“myapp.py”(以#! /usr/bin/env python 开头),并使其可用。这可以下载,然后使用myapp.py [ARGUMENTS]python myapp.py [ARGUMENTS] 运行。但是,将我的应用程序限制为单个 .py 文件有几个缺点,包括限制我组织代码的能力以及难以使用第三方依赖项。

相反,我想分发我自己代码的几个文件的内容,以及一些(纯 Python)依赖项。是否有任何工具可以将所有这些打包到一个文件中,可以使用现有的 Python 安装轻松下载和运行?

编辑:请注意,我需要这些应用程序便于最终用户运行。他们不太可能安装pip,也不太可能安装 Python 核心之外的任何其他东西。使用 PyInstaller,我可以生成一个文件,这些用户可以从网上下载并使用一个命令运行(或者,如果没有参数,只需双击)。有没有办法在不使用 PyInstaller 的情况下实现这种易用性(即无需冗余捆绑 Python 运行时)?

【问题讨论】:

  • 对于第二种(小)解决方案,为什么不使用 pip?
  • 你有非常相似的问题here about Windowshere in general
  • 你提到了各种平台,但没有提到它们是什么。 “sudo apt-get install package”对您的最终用户来说足够简单吗?
  • “是否有任何工具可以将所有这些打包到一个文件中,可以使用现有的 Python 安装轻松下载和运行?” - 获取资源并压缩它们。您将获得一个可以轻松下载并在任何现有兼容 Python 安装中运行的文件。 :)
  • @snapshoe:假设最终用户安装了 Python(可能是系统自带的,也可能是他们自己安装的),并且他们有足够的信心从命令行运行 python myapp.py [ARGUMENTS]。在环境方面,我正在寻找一种方法来运行一组 Python 文件(我自己的和第三方的依赖项),就像所有文件都被连接成一个巨大的脚本一样容易。如果一个系统可以运行后者,我希望它能够运行前者。

标签: python packaging software-distribution


【解决方案1】:

我不喜欢单一文件的想法,因为它会成为维护负担。我会探索一种类似下面的方法。

我已经成为 Python 虚拟环境的忠实拥护者,因为它允许您从操作系统安装中分离出您的应用程序依赖项。想象一个场景,您当前要分发的应用程序使用 Python 包 requests v1.0。一段时间后,您创建了另一个使用requests v2.3 的要分发的应用程序。您最终可能会在要并排安装两个应用程序的系统上遇到版本冲突。虚拟环境解决了这个问题,因为每个应用程序都有自己的包位置。

创建虚拟环境很容易。安装virtualenv 后,只需运行即可,例如virtualenv /opt/application/env。现在,您的应用程序有了一个独立的 Python 环境。此外,虚拟环境非常容易清理,只需删除 env 目录即可。

您需要一个setup.py 文件来将您的应用程序安装到环境中。假设您的应用程序使用requests v2.3.0,您的自定义代码位于名为acme 的包中,您的脚本名为phone_home。您的目录结构如下所示:

acme/
    __init__.py
    models.py
    actions.py
scripts/
    phone_home
setup.py

setup.py 看起来像这样:

from distutils.core import setup


install_requires = [
    'requests==2.3.0',
]

setup(name='phone_home',
      version='0.0.1',
      description='Sample application to phone home',
      author='John Doe',
      author_email='john@doe.com',
      packages=['acme'],
      scripts=['scripts/phone_home'],
      url='http://acme.com/phone_home',
      install_requires=install_requires,
)

您现在可以从您的项目中制作一个 tarball 并随心所欲地托管它(您自己的 Web 服务器、S3 等):

tar cvzf phone_home-0.0.1.tar.gz .

最后,您可以使用pip 将您的包安装到您创建的虚拟环境中:

/opt/application/env/bin/pip install http://acme.com/phone_home-0.0.1.tar.gz

然后您可以运行phone_home

/opt/application/env/bin/phone_home

或者在 /usr/local/bin 中创建一个符号链接来简单地使用 phone_home 调用脚本:

ln -s /opt/application/env/bin/phone_home /usr/local/bin/phone_home

上述所有步骤都可以放在一个 shell 脚本中,这将使该过程成为单命令安装。

稍加修改后,这种方法非常适用于开发环境;即使用 pip 安装/引用您的开发目录:pip install -e . 其中. 指的是当前目录,您应该与setup.py 一起位于项目目录中。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    您可以按照 cmets 中的建议使用 pip。您需要在项目中创建MANIFEST.insetup.py 以使其可安装。您还可以添加模块作为先决条件。更多信息可以在这个问题中找到(不是特定于 Django):

    How do I package a python application to make it pip-installable?

    这将使您的模块在 Python 中可用。然后,您可以让用户通过python path/run.py./path/run.py(具有+x 权限)或python -c "some code here"(例如,别名)来运行运行您的模块的文件。

    您甚至可以让用户从 git 公共存储库安装,像这样

    pip install git+https://bitbucket.org/yourname/projectname.git
    

    ...在这种情况下,他们也需要 git。

    【讨论】:

    • 您也可以使用 pip 安装应用程序的 tarball;这消除了 git 要求。例如:pip install https://yourdomain.com/application.tar.gz
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 2016-09-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    相关资源
    最近更新 更多