【问题标题】:How to use virtualenv with Google App Engine SDK on Mac OS X 10.6如何在 Mac OS X 10.6 上将 virtualenv 与 Google App Engine SDK 一起使用
【发布时间】:2011-04-21 00:02:25
【问题描述】:

我正在拔头发试图解决这个问题,因为直到上周我一直在工作,但不知何故它坏了。

当我为 Google App Engine 应用设置 virtualenv 并使用 dev_appserver.py 启动应用时,我在导入标准库时遇到错误(例如“ImportError: No module named base64”)。

这就是我正在做的事情:

(使用系统Python)

virtualenv --python=python2.5 --no-site-packages ~/.virtualenv/foobar

然后我将 gae.pth 文件添加到包含 Google App Engine 库的 ~/.virtualenv/foobar/lib/python2.5/site-packages/

/usr/local/google_appengine
/usr/local/google_appengine/lib/antlr3
/usr/local/google_appengine/lib/cacerts
/usr/local/google_appengine/lib/django
/usr/local/google_appengine/lib/fancy_urllib
/usr/local/google_appengine/lib/ipaddr
/usr/local/google_appengine/lib/webob_1_1_1
/usr/local/google_appengine/lib/yaml/lib

(这是基于this answer。)

然后我获取我的“foobar”virtualenv 并尝试使用dev_appserver.py 启动我的应用程序。

服务器启动,但第一个请求出错,出现上述“ImportError: No module named base64”。如果我访问管理控制台,我会收到“ImportError: No module named cgi”。

如果我启动 python,我可以加载这些模块。

>>> import base64
>>> base64.__file__
'/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/base64.py'

SDK 的沙盒功能似乎阻止了这些库的加载。但就像我说的那样,我直到上周才开始工作......有些东西发生了变化,或者我无意中破坏了我的 virtualenv,我不知道我是如何让它工作的。

软件版本:

Google App Engine SDK 1.3.7
Mac OS X 雪豹 10.6.4
虚拟环境 1.5.1

更新:针对 Alan Franzoni 的问题:

我正在使用 Mac OS X 附带的系统 Python。我通过 easy_install 安装了 virtualenv。我今天升级到 virtualenv 1.5.1 试图解决这个问题。

如果我使用 virtualenv python 运行python /usr/local/bin/dev_appserver.py,问题仍然存在。如果我停用 virtualenv 并使用系统 python2.5 运行该命令,它就可以工作。 (另外,我可以使用 GoogleAppEngineLauncher 启动我的应用程序。)

这是一个完整的堆栈跟踪(这个使用了 Kay 框架,但问题与 webapp 相同):

Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 3206, in _HandleRequest
    self._Dispatch(dispatcher, self.rfile, outfile, env_dict)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 3149, in _Dispatch
    base_env_dict=env_dict)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 525, in Dispatch
    base_env_dict=base_env_dict)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 2402, in Dispatch
    self._module_dict)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 2312, in ExecuteCGI
    reset_modules = exec_script(handler_path, cgi_path, hook)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 2208, in ExecuteOrImportScript
    exec module_code in script_module.__dict__
  File "/Users/look/myapp/kay/main.py", line 17, in <module>
    kay.setup()
  File "/Users/look/myapp/kay/__init__.py", line 122, in setup
    from google.appengine.ext import db
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 1287, in Decorate
    return func(self, *args, **kwargs)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 1937, in load_module
    return self.FindAndLoadModule(submodule, fullname, search_path)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 1287, in Decorate
    return func(self, *args, **kwargs)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 1839, in FindAndLoadModule
    description)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 1287, in Decorate
    return func(self, *args, **kwargs)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver.py", line 1790, in LoadModuleRestricted
    description)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/db/__init__.py", line 81, in <module>
    import base64
ImportError: No module named base64

【问题讨论】:

  • 能否请您剪切并粘贴此类错误的完整输出?如果您使用“python /usr/local/bin/dev_appserver.py”,错误是否保持不变?另外,您是如何通过 setuptools 安装 virtualenv 的?你使用系统python2.5,macports一,这些的任何组合?
  • 感谢您的回复。我已更新帖子以回答您的问题。
  • 你能输入“which python”来确保你运行的是 virtualenv Python 吗?
  • 如果你交互式地运行 virtualenv 的 python,import base64 会成功吗? (我已经让 GAE 在 OSX 上的 virtualenv 中使用 GAE 的 svn trunk 源工作,而不是安装 .dmg。如果有帮助,我可以发布我的步骤作为答案,但我现在只有 helloworld 教程应用程序,而不是任何类型的复杂应用程序。)
  • SDK ≥ 1.6.1 + gae.pth 是让 SDK 在多虚拟环境设置上保持同步的好方法。 By adding setup.py + MANIFEST.in 我设法使其 pip 可安装 = 100% 自动化 + 使 SDK 在 vi​​rtualenv 中运行无需修补

标签: python macos google-app-engine virtualenv


【解决方案1】:

这是一个带有 GAE SDK 的issue 4339,它已得到确认,并且在错误条目中提供了两个稍微不同的补丁,使其能够正常工作。

发生的情况是dev_appserver.py 通过禁止访问任何非系统 python 模块来设置受限制的 python 环境,它通过从os 模块的位置计算系统 python 文件夹来做到这一点。在 virtualenv 实例中,os.py 被符号链接到 virtualenv 但被编译直接进入 virtualenv,这是 dev_appserver 使用的路径,有效地阻止了从系统 python 库访问任何不是的模块由 virtualend 链接,这是其中的大多数。解决办法是“祝福”两条路。

【讨论】:

  • 问题 4339 刚刚作为 SDK 版本 1.6.1 的已修复问题关闭。我试过了,它又对我有用了!
【解决方案2】:

Google AppEngine SDK 为了将其安装拉入 sys.path 使用了很多技巧,而这些技巧依赖于实际文件的路径。我认为它失败的原因可能有很多。 SDK 不会将自身安装为真正的 python 包,virtualenv 不会进行完整的沙盒,它只是设置一个环境(显然)并更改 sys.path。而 GAE SDK 也是这样做的,它们都相互干扰,SDK 发展迅速,变化频繁,所以这条路非常坎坷。

如果您能解释一下您想要达到的目标,可能会更好。我的猜测是您正在尝试创建一个干净的环境以确保应用程序没有可用的第 3 方模块。如果这个猜测是正确的,我会按照here 的描述通过需求文件将 GAE SDK 安装到 virtualenv 中。

【讨论】:

    【解决方案3】:

    我认为,由于您已经使用 --no-site-packages 选项设置了 virtualenv,因此您需要将 SDK 安装到环境中。 --no-site-packages 将您正在配置的开发环境与您计算机上的任何其他 Python 安装分开,因此,当您似乎已配置它时,您正在调用一个不存在的模块(在环境中),它是为什么它与 env 停用(然后从默认操作系统安装运行 Python)一起工作。如果您希望能够访问环境之外的模块,请尝试在没有 --no-site-packages 选项的情况下设置开发环境。

    【讨论】:

    • 通常有 --no-site-packages 和 virtualenv 以避免污染
    【解决方案4】:

    我的谈话有点晚了,但我也遇到了同样的问题,我偶然发现了gae_installer,您可以使用pip install gae_installer 以通常的方式安装它。这会将 google app engine (gae) sdk 直接放入您的 python 路径中。希望其他人觉得这很有用。

    【讨论】:

    • 您是在虚拟环境内部还是外部执行此操作?
    【解决方案5】:

    和 bozzo 一样的答案。以下是说明:

    这在 GAE 的 Issue 4339 中有所描述。以下是解决方法:

    1. 在这里下载补丁:patch
    2. 将补丁移至 google_appengine/google/appengine/tools/
    3. 将工作目录更改为与上述相同的路径
    4. 类型:patch -p0

    【讨论】:

      猜你喜欢
      • 2011-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-01
      相关资源
      最近更新 更多