如何将发布自己的Python程序包到PyPI?

上一篇

基于《Flask——留言板》,我们准备将他发布PyPI上,那么我们应该怎么进行操作呢?

setup.py是什么?

首先我们先思考一个问题,熟悉Python开发的程序猿们,都知道我们会经常使用到一个叫做setup.py的文件。Python的封装离不开setup.py。

那么问题就来了, setup.py是一个什么文件呢,有什么作用?

将开发完毕的程序封装成包,可以方便其他用户或其他项目拿去用。而封装的大部分时间都要消耗在编写setup.py上。我们用setup.py来设置python程序包的信息、定义程序包。setup.py 这个文件名是python中定好的,不可以更改。我们要在这个文件中定义程序包的名称、包及依赖包的信息等元数据。

有了setup.py之后,我们便能在命令行中执行注入python setup.py install等预报相关的操作。另外,讲程序包注册到PyPI的操作也需要通过setup.py进行。

编写setup.py

首先,我们来做出一个能与性的setup.py空壳。

如何将发布自己的Python程序包到PyPI?

setup.py空壳

现在我们就可以执行setup.py的命令了。各位可以通过--help-command选项查看setup.py提供的命令。下面列举了一些有代表性的命令。

如何将发布自己的Python程序包到PyPI?

--help-commands

build 构建安装所需的全部内容

clean 清楚bulid构建的所有临时文件

install 安装build目录下的全部内容

sdist 创建源码包(tar,zip)

bdist 创建二进制包

bdist_dumb 创建dumb格式的二进制包

bdist_rpm 创建rmp格式的二进制包

bdist_wininst 创建面向window的安装包

upload 将二进制包上传至pypi

register 将程序包注册到pypi上

check 检查程序包的设置值是否正确

develop 以开发模式安装程序包

upload_docs 向pypi上传文档

install 和 develop的区别

Install 将程序包复制拷贝到主机的python下的site-packages下,实际调用过程:site-package->lib。

develop 将程序包链接到主机的python下的site-packages 下,实际调用过程:site-package->build(源码程序包)

下面我们来创建最基本的源码包。源码包需要通过python setup.py sdist命令创建。

如何将发布自己的Python程序包到PyPI?

python setup.py sdist

现在,dist目录下已经生成了guestbook-0.0.0.tar.gz文件。这个tar.gz文件目录目前只包含set丿。py。

另外,我们在执行过程中看到了几个warning。这些warning指出的项目最好都设置一下,后面我们会学习如何进行设置。

项目结构的设置

首先,我们来了解一下Python项目一般的目录结构。当封装对象只有一个.py文件是,其结构如下图所示。

如何将发布自己的Python程序包到PyPI?

单文件项目结构

如果封装对象目录下包含多个.py或模板等文件,则结构如下图所示。

如何将发布自己的Python程序包到PyPI?

多文件目录结构

将要发布的项目源码放置到packagename文件中,将项目的入口文件重命名为__init__.py。并且修改packaename文件夹名为setup.py中设置的name,最终形成如下图所示的结果。

如何将发布自己的Python程序包到PyPI?

guestbook打包项目结构

如何将发布自己的Python程序包到PyPI?

guestbook打包项目结构

setup.py——设置最低限度内容的程序包信息

接下来我们将在setup.py中设置最低限度内容的程序包的信息。

如何将发布自己的Python程序包到PyPI?

setup.py

MANIFEST.in——设置捆绑的文件

为将HTML文件、CSS文件等程序包资源与程序包捆绑在一起,我们需要用MANIFEST.in来制定封装对象文件。

这里我们在setup.py所在的目录下创建MANIFEST.in文件,制定封装对象文件的范围。

如何将发布自己的Python程序包到PyPI?

MANIFEST.in文件代码

recursive-include表示捆绑制定目录下所有与制定类型一致的文件。

现在我们希望使用这个程序包的环境能安装这些捆绑好的程序包资源。为此,我们需要将前面提到的install_package_data指定为True,这一点至关重要。

MANIFEST.in还可以制定捆绑guestbook应用不使用的非程序包资源文件,比如LICENSE.txt。在发布程序包是最好把许可文件也捆绑进去。

假如我们使用BSD许可,并在LICENSE.txt文件中描述了许可条款。接下来,我们需要在MANIFEST.in里添加对它的捆绑制定。

include会捆绑所有与制定类型一致的文件。所以添加了指定语句后,LICENSE.txt文件就和程序包捆绑在了一起。另外,我们要安装的是guestbook目录,而LICENSE.txt文件并不在该目录下,所以LICENSE.txt文件并不会被安装到使用该程序包的环境中。

MANIFEST.in有许多中描述方式,不但可以将某个扩展名的文件全部捆绑起来,还可以剔除特定拓展名的全部文件。MANIFEST.in的详细描述方法请查阅Python的参考手册。(https://docs.python.org/2.7/distutils/sourcedist.html)

确定运行情况

为查看前面的设置是否正确,在安装时请加上-e(--editable)选项进行原地安装(在原目录下直接转为安装状态)。这样一来,我门在开发过程就不用每改一次都重新安装一遍了。

如何将发布自己的Python程序包到PyPI?

pip安装演示

如何将发布自己的Python程序包到PyPI?

pip freeze 显示模块列表

现在guestbook-1.0.2已经安装到环境中了。我们可以看到,记录程序包元数据位置的guestbook.egg-link文件被安装到环境中了。easy-install.path文件中添加了guestbook的源码位置。另外,Flask及相关程序包也都安装好了。

这样一来,我们在其他PC或服务器上构建环境时,就不必再去一个个地安装依赖包了。如果今后需要添加或更改一来库,各位只要按照之前讲的流程更新setup.py,然后再执行一次pip install即可。

创建执行命令

我们都知道,我们安装完许多Python库的时候,都会生成很多命令,供我们去操作。如果想要让下载我们发布的程序包的用户用起来更方便,我们最好也要生成一些用户命令。这里我们通过设置setup.py,让其自动生成guestbook命令。

如何将发布自己的Python程序包到PyPI?

entry_points

但是guestbook/__init__.py中没有main函数,所以我们需要添加这个函数,具体代码如下。

如何将发布自己的Python程序包到PyPI?

main方法

然后我们再次执行安装命令,看看是否能生成guestbook命令。

即便是在editable安装的状态下,如果想反映出对元信息进行的修改(比如添加命令、更改依赖库等),也需要重新执行一次安装命令。

如何将发布自己的Python程序包到PyPI?

linux下运行情况

可以看到,guestbook命令已经生成,而且可以正常运行。

如何将发布自己的Python程序包到PyPI?

window下的坑

window的坑,我就无语了,调试半天,将所有的文件都换成ascii格式,依旧错,无语了,后面我会教大家一种如何生成exe安装包,我们可以通过那个实现我们这个环境的安装与运行。

window下的错误详情:https://www.python.org/dev/peps/pep-0263/

创建源码发布程序包

创建用于发布的程序包时,执行python setup.pysdist命令。

如何将发布自己的Python程序包到PyPI?

python setup.pysdist

如何将发布自己的Python程序包到PyPI?

guestbook.egg-info

这样,我们就在dist目录下生成了guestbook-1.0.2.tar.gz。 tar.gz文件包含guestbook/__init__.py、setup.py.LICENSET.txt、html、css等文件。

现在只要将这个文件放到我们想安装应用的环境中,就可以运行pip install guestbook-1.0.2.tar.gz.zhge tar.gz,直接从文件进行安装。

README.rst——开发环境设置流程

下面我们来描述设置流程说明书,总结搭建流程。我们前面讲到的流程如下。

  1. 安装guestbook

  2. guestbook运行项目

如何将发布自己的Python程序包到PyPI?

环境搭建运行流程

扩展名为.rst的文件是用reStructuredText(reST)语法描述的文本文件。一般说来,Python项目都会选用reST语法来写README.rst。关于reST语法,我会在别的文章中做详细介绍,或者大家自行了解。

如何将发布自己的Python程序包到PyPI?

README.rst

各位请注意,我们在安装流程中写的是直接安装,但在开发流程中写的确实用pip install -e 进行安装。而关于这二者的区别,我们并没有在README.rst文件中提及。这是因为我们认为于都这篇文章的人应该懂得如何使用pip的-e选项,知道有它和没它的不同。

变更依赖包

项目的依赖包是Flask。但是,我们很难字开发初期就确定好一款应用程序内的所有依赖包,有些时候还会放弃当前的包而改为其他的。他别是周期短、开发频繁的项目,往往没发布一次都会变更一次依赖包。

举个例子,假设我们放弃Flask改用Bottle。这是如果直接用pip命令安装了Flask或Bottle,那就必须将这一步骤告知其他开发者甚至未来的自己。

setup.py里记录着依赖包的信息,因此我们只需要更改setup.py的设置即可。如果改写了setup.py的install_requires行,需要再次执行pip install --editable ./

这一步骤的命令和安装时的命令一样,因此不需要修改流程说明书。只要其他新建项目环境的开发者执行了pip install --editable ./命令,就能安装好改项目所需的全部程序包.

另外,最好在README.rst中添加如下所示的流程。

如何将发布自己的Python程序包到PyPI?

相关推荐