打包命令行应用程序以进行分发?

时间:2014-06-10 14:19:33

标签: python packaging software-distribution

我目前正在用Python编写命令行应用程序,需要以最易于下载和运行的方式向最终用户提供。对于那些可能没有安装Python(2.7)的Windows用户,我打算使用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,我可以生成一个文件,这些用户可以从Web下载并使用一个命令运行(或者,如果没有参数,只需双击)。有没有办法在不使用PyInstaller的情况下实现这种易用性(即没有冗余地捆绑Python运行时)?

2 个答案:

答案 0 :(得分:7)

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

我已成为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旁边的项目目录中。

希望这有帮助!

答案 1 :(得分:5)

您可以按照评论中的建议使用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。