Debian软件包如何从PyPI安装Python模块?

这个问题试图补充this one。 我有一个使用PyPI的第三方模块的Python应用程序。我想将我的应用程序打包成一个Debian软件包,但不知道如何处理那些不在Debian/Ubuntu软件仓库中(也没有打包成Debian软件包)的Python依赖。 解决方案 #1: 将PyPI的模块直接构建到我的Debian软件包中。 解决方案 #2: 使用stdeb为我所需的所有PyPI模块创建Debian软件包,并将它们添加到Debian/Ubuntu软件仓库中。
实际上,我需要一个解决方案 #3,因为我希望在安装我的Debian软件包时安装PyPI依赖项,最好是安装到一个虚拟环境中!
那么解决方案 #3是什么呢?我需要调整DEBIAN/preinst维护者脚本吗?

你可以描述一下为什么需要创建一个Debian包吗?你的Python应用程序是否需要非Python资源? - Jonathan
@Jonathan 我希望用户能够从Ubuntu软件中心安装我的应用程序。我认为我需要一个*.deb文件来实现这一点。我的Python应用程序不需要非Python资源,只需要第三方的Python模块。 - andri_ch
1@Jonathan Debian软件包是Ubuntu的标准安装方法。可以轻松分发.deb文件,或者在Launchpad上设置私有仓库或PPA。 - MestreLion
3个回答

我已经与Debian IRC频道的一些维护者irc://irc.debian.org#debian-mentors交谈过,询问了完全相同的事情,总体共识是: 解决方案#1: 将依赖项集成到您的软件包中,通过将它们的源文件复制为单个代码库,这是非常不被赞同的。这将违背处理依赖关系、更新、版本控制等功能的打包系统的目的。 解决方案#3: 在安装二进制(.deb)文件时,动态下载非Debian软件包是一个严重的安全风险,绝对不可行。你甚至无法通过提取.deb文件来检查依赖关系,因为它们是在安装时下载和安装的。这种方法完全绕过了存储库系统。没有关注安全的用户会满意于一个在幕后(并且作为root用户,请记住!)从不受信任的来源下载额外的不受信任软件的软件包。是的,这需要修改DEBIAN/postinst(或preinst)并执行wget(或在您的情况下,pip install),这是Flash、Oracle Java、Steam等软件所采用的方法。但那是专有的、闭源的软件,所以它们的安全性本来就不存在。
解决方案1.5:
你没有提到,但你可以只在构建时集成依赖项,即在源包(.orig.tar.gz、.debian.tar.gz、.dsc三个文件的组合)中下载PyPi上的依赖项,并在创建"二进制"包(.deb)时进行。pip install的指令将放在debian/rules中(注意小写的debian,与二进制包不同),并在执行debuild或dpkg-buildpackage时执行。
这是第一种方法和第三种方法之间的折衷方案。它减轻了第三种方法的一些问题:至少您可以检查最终产品,并且.deb在安装时不需要互联网访问。所有的风险和负担都转移到了软件包维护者身上。但是,它与第一种方法有相同的问题,因为它绕过了大部分打包系统基础设施。毕竟,处理依赖关系(版本、更新、要求、冲突)正是dpkg/apt被创建的原因! :)

解决方案#2:

唯一正确的方法™。您为依赖项创建Debian软件包,在软件包中将它们列为要求,并发送所有的.debs或源码软件包。

从那里,您有几个选择:

  • 提交源代码包,包括您的软件及其依赖项,以便将其纳入Debian。如果被接受,它们将自动对所有Debian用户开放,包括所有派生版本如Ubuntu。

  • 将源代码包上传到Launchpad,从而创建一个PPA,任何Ubuntu用户(以及其派生版本如Linux Mint)都可以轻松添加和安装。

  • 在您的网站上托管自己的Debian存储库,任何基于Debian的系统用户都可以将其添加到他们的/etc/apt/sources.list.d中,并使用apt基础设施进行下载、安装和更新(就像上面所述!)。

  • 托管.deb文件以供直接下载和安装。不涉及apt或自动更新。

至于如何打包您的PyPi依赖项(以及您的Python软件!),有许多工具和参考资料可使该过程变得简单:

  • stdeb,如你所提到的。老牌而靠谱。

  • Pybuild,来自Debian的一款新奇而令人惊叹的工具,取代了stdeb

还有许多有用的参考资料:

需要帮助吗?查阅以下内容:


有一个叫做 pypi2deb 的工具,可以从 pypi 获取软件包并将其转换为 deb 包。

很不幸的是,目前看起来它已经不再积极开发了。 - zezollo

我认为你只需要在.deb软件包的postinst脚本中添加相关的命令行代码。在这个答案中找到,更多细节请参考官方Debian指南