使用Setuptools部署

Setuptools是一个扩展库,通常用于发布Python的库和扩展。它扩展自distutils,一个Python自带的基础的模块安装系统,支持各种更加复杂的结构,使得发布大型的应用更加容易:

  • 支持依赖:库或者应用可以声明它依赖的其它的库的一个列表,它们将会自动为你安装好。
  • 注册软件包: setuptools 将你的包注册到您的安装的 Python 环境中。这使得你可以使一个包中的代码查询另一个包所提供的信息。 这一系统最知名的 特性就是对接口机制的支持,也就是说一个包可以声明自己的一个接口,从而允许 其他的包通过这个接口对自己进行扩展。
  • 安装管理pip可以为你安装其它的库。

如果您从python.org安装了Python 2(> = 2.7.9)或Python 3(> = 3.4),您的系统上已经有pip和setuptools。否则,您需要自己安装它们。

Flask本身以及你在PyPI上能够找到的所有库都是通过setuptools或distutils发布的。

在这种情况下,我们假设您的应用程序名为yourapplication.py,并且您未使用模块,而是使用package 如果您还没有将您的应用转化为包的形式, 请参考前文 大型应用 的内容查找如何做到这件事。

使用setuptools的工作部署是进入更复杂和更自动化的部署方案的第一步。如果要完全自动化过程,还请阅读Deploying with Fabric章节。

基本设置脚本

因为你已经安装好Flask,所以你的系统上已经有setuptools了。Flask已经依赖setuptools。

标准免责声明适用于:you better use a virtualenv

您的设置代码始终位于应用程序旁边的名为setup.py的文件中。 为文件 指定这一名称只是为了方便,不过一般来说每一个人自然而然的在程序目录下 寻找这个文件,所以您最好别改变它。

Flask应用程序的基本setup.py文件如下所示:

from setuptools import setup

setup(
    name='Your Application',
    version='1.0',
    long_description=__doc__,
    packages=['yourapplication'],
    include_package_data=True,
    zip_safe=False,
    install_requires=['Flask']
)

请记住,您必须显式地列出子包。如果希望setuptools自动查找软件包,可以使用find_packages函数:

from setuptools import setup, find_packages

setup(
    ...
    packages=find_packages()
)

setup函数的大多数参数应该是自解释,include_package_datazip_safe可能不是。include_package_data告诉setuptools查找MANIFEST.in文件,并安装所有与软件包数据匹配的条目。 我们使用这个特性来分发 Python 模块自带的静态文件和模板(参考 分发代码)。 zip_safe标志可用于强制或阻止zip存档创建。 通常情况下,您不希望您的包以 ZIP 压缩 包的形式被安装,因为一些工具不支持这种方式,而且这样也会让调试代码异常麻烦。

标记建筑

区分发布版本和开发版本是非常有用的。添加setup.cfg文件以配置这些选项。

[egg_info] tag_build = .dev tag_date = 1

[aliases] release = egg_info -RDb''

运行python setup.py sdist将创建一个带有“.dev” flaskr-1.0.dev20160314.tar.gz运行python setup.py 发布 sdist版本:flaskr-1.0.tar.gz

分配资源

如果你试图安装刚刚创建的包,你会发现诸如statictemplates这样的文件夹没有安装进去。 这是因为 distribute 不知道该把哪些文件添加进去。 你应该做的是在setup.py文件的同级目录下创建一个MANIFEST.in文件。这个文件列出所有应该加入到压缩包中的文件:

recursive-include yourapplication/templates *
recursive-include yourapplication/static *

Don’t forget that even if you enlist them in your MANIFEST.in file, they won’t be installed for you unless you set the include_package_data parameter of the setup function to True!

声明依赖

依赖在install_requires参数中声明为一个列表。 链表的每个元素是 需要从 PyPI 下载并安装的包的名字,默认将总会下载安装最新的的版本。 但是您也 可以指定需要的最大和最小的版本区间。 以下是一个例子:

install_requires=[
    'Flask>=0.2',
    'SQLAlchemy>=0.6',
    'BrokenPackage>=0.7,<=1.0'
]

正如前面提到的,依赖关系是从PyPI拉下来的。如果您需要依赖一个不能在 PyPI 当中 被下载的包,比如这个包是个内部的,您不想与别人分享。只是做它好像有一个PyPI条目,并提供了一个替代位置的列表,其中setuptools应该查找tarball:

dependency_links=['http://example.com/yourfiles']

请确认那个页面包含一个文件夹列表,且页面上的连接被指向实际需要下载的软件包。 如您有一个内部服务器包含有这些包,将 URL 指向这个服务器。

安装/开发

要安装您的应用程序(最好是在virtualenv中),只需使用install参数运行setup.py脚本即可。 这会将您的应用安装到一个 virtualenv 的 site-packages 文件夹下面,并且同时 下载和安装所有的依赖包:

$ python setup.py install

如果您在软件包上开发,并且希望安装需求,可以使用develop命令:

$ python setup.py develop

这有一个优点,只是安装一个链接到site-packages文件夹,而不是复制数据。然后,您可以继续处理代码,而无需在每次更改后再次运行install