如何在Google App Engine上管理第三方Python库?(virtualenv?pip?)
在Google App Engine上管理第三方Python库的最佳策略是什么?
假设我想使用Flask,一个用于开发网页应用的框架。有一篇博客提到这样做,但我觉得这不太对:
$ cd /tmp/
$ wget http://pypi.python.org/packages/source/F/Flask/Flask-0.6.1.tar.gz
$ tar zxf Flask-0.6.1.tar.gz
$ cp -r Flask-0.6.1/flask ~/path/to/project/
(... repeat for other packages ...)
我相信有更好的方法来管理第三方代码,特别是当我想跟踪版本、测试升级,或者当两个库共享一个子目录时。我知道Python可以从压缩文件中导入模块,而且pip可以使用一个很棒的REQUIREMENTS文件。我还看到pip有一个zip
命令可以在GAE中使用。
7 个回答
那么简单点说:
$ pip install -r requirements.txt -t <your_app_directory/lib>
创建或编辑 <你的应用目录>/appengine_config.py
文件:
"""This file is loaded when starting a new application instance."""
import sys
import os.path
# add `lib` subdirectory to `sys.path`, so our `main` module can load
# third-party libraries.
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib'))
更新:
谷歌更新了他们的示例,变成了 appengine_config.py
,像这样:
from google.appengine.ext import vendor
vendor.add('lib')
注意:虽然他们的示例中有 .gitignore
文件会忽略 lib/
目录,但如果你使用 git-push
部署方法,仍然需要把这个目录放在源代码管理中。
这是我做的方式:
- 项目文件夹
- .Python
- bin
- lib
- python2.5
- site-packages
- < 在这里用 pip 安装包 >
- site-packages
- python2.5
- include
- src
- app.yaml
- index.yaml
- main.yaml
- < 在 ../lib/python2.5/site-packages 中创建 pip 安装包的符号链接 >
项目
文件夹是虚拟环境的顶层目录。我使用以下命令来创建虚拟环境:
cd project
virtualenv -p /usr/bin/python2.5 --no-site-packages --distribute .
src
文件夹是你所有代码的地方。当你把代码部署到 GAE(谷歌应用引擎)时,*只* 部署 src 文件夹中的内容,其他的都不要。appcfg.py
会处理符号链接,并把库文件复制到 GAE。
我不把我的库安装成 zip 文件,主要是为了方便,如果我需要查看源代码的话,我经常出于好奇去看。不过,如果你真的想把库打包成 zip,可以把以下代码片段放到你的 main.py 中:
import sys
for p in ['librarie.zip', 'package.egg'...]:
sys.path.insert(0, p)
这样之后,你就可以像往常一样导入你的压缩包了。
需要注意的是 setuptools 的 pkg_resources.py
。我直接把它复制到我的 src
文件夹,这样我其他的符号链接包就可以使用它。要留意任何使用 entry_point
的东西。在我的情况下,我使用的是 Toscawidgets2,我不得不深入源代码手动连接各个部分。如果你有很多依赖于 entry_point
的库,这可能会变得很麻烦。
(2021年6月) 这篇文章已经有十多年了,所以现在需要一个更新的回答。
- Python 3:在
requirements.txt
文件中列出你需要的第三方库和版本号;在你部署时,谷歌会自动安装它们。(如果你决定把应用迁移到谷歌的 Cloud Functions 或 Cloud Run,也可以用这个方法。) - Python 2 没有 内置的第三方库(普通的第三方库):
- 像上面那样创建
requirements.txt
- 通过
pip install -t lib -r requirements.txt
安装/自打包/复制这些库到本地,比如放到lib
文件夹里 - 创建
appengine_config.py
,具体内容可以参考 这页的第5步
- Python 2 有 内置的第三方库(特殊的第三方库):
- 上面提到的所有第三方库都是“内置的”,也就是说它们在App Engine服务器上是可用的,所以你不需要像第2点那样把它们复制到你的应用里
- 只需在
app.yaml
的libraries:
部分列出它们和可用的版本,像这样 - (不要把内置库放在
requirements.txt
里,也不要用pip install
本地安装它们,除非你想自打包,比如说你需要内置库的更新版本。) - 像上面那样创建
appengine_config.py
。
如果你有一个同时使用了内置和非内置第三方库的Python 2应用,按照第2和第3点的方法来做(把内置库放在 app.yaml
里,非内置库放在 requirements.txt
里,然后运行上面的 pip install
命令)。在第二代运行环境(比如Python 3)中,一个改进就是这些关于第三方库的麻烦都不再存在了(见第1点)。
示例:Flask
Flask是一个第三方的微型网页框架,这个问题中它是个有趣的例子。对于Python 3,所有的库都放在 requirements.txt
里,所以你只需把 flask
加到这个文件中,就完成了。(然后直接部署就可以了。)
对于Python 2,这个情况更有趣,因为它是一个内置库。不幸的是,App Engine服务器上的版本是 0.12
。现在我们已经到了 2.0.3
以上,谁还想用 那个呢?!所以你不能像其他内置库那样把它放在 app.yaml
里,而是要假装内置版本不存在,把它放在 requirements.txt
里,然后运行 pip2 install -t lib -r requirements.txt
把它和你的应用代码打包在一起。(不过,Python 2的最终版本是 1.1.4
,所以安装的就是这个版本。)