如何在Google App Engine上管理第三方Python库?(virtualenv?pip?)

64 投票
7 回答
21946 浏览
提问于 2025-04-16 11:00

在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中使用。

(注意:有一些类似的问题 — 1, 2, 3, 4, 5 — 但这些问题都是特定情况,并没有真正回答我的问题。)

7 个回答

46

那么简单点说:

$ 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 部署方法,仍然需要把这个目录放在源代码管理中。

70

这是我做的方式:

  • 项目文件夹
    • .Python
    • bin
    • lib
      • python2.5
        • site-packages
          • < 在这里用 pip 安装包 >
    • 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 的库,这可能会变得很麻烦。

2

(2021年6月) 这篇文章已经有十多年了,所以现在需要一个更新的回答。

  1. Python 3:在 requirements.txt 文件中列出你需要的第三方库和版本号;在你部署时,谷歌会自动安装它们。(如果你决定把应用迁移到谷歌的 Cloud FunctionsCloud Run,也可以用这个方法。)
  2. Python 2 没有 内置的第三方库(普通的第三方库):
  • 像上面那样创建 requirements.txt
  • 通过 pip install -t lib -r requirements.txt 安装/自打包/复制这些库到本地,比如放到 lib 文件夹里
  • 创建 appengine_config.py,具体内容可以参考 这页的第5步
  1. Python 2 内置的第三方库(特殊的第三方库):
  • 上面提到的所有第三方库都是“内置的”,也就是说它们在App Engine服务器上是可用的,所以你不需要像第2点那样把它们复制到你的应用里
  • 只需在 app.yamllibraries: 部分列出它们和可用的版本,像这样
  • (不要把内置库放在 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,所以安装的就是这个版本。)

撰写回答