如何在Mac OS X 10.6上使用virtualenv与Google App Engine SDK

时间:2010-10-04 20:14:24

标签: python macos google-app-engine virtualenv

我正在把头发拉出来试图解决这个问题,因为我让它一直工作到上周,不知何故它破了。

当我为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:没有名为cgi的模块”。

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

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

SDK的沙盒似乎阻止了这些库的加载。但就像我说的那样,直到上周我才开始工作......有些事情发生了变化,或者我无意中打破了我的虚拟现实,我无法弄清楚我是如何让它在第一时间起作用的。

软件版本:

Google App Engine SDK 1.3.7
Mac OS X Snow Leopard 10.6.4
virtualenv 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

5 个答案:

答案 0 :(得分:15)

这是GAE SDK的issue 4339,已经确认,并且错误条目中有两个略有不同的补丁可以使其正常工作。

dev_appserver.py通过禁止访问任何非system-python模块来设置受限python环境,并通过从os模块的位置计算系统python文件夹来实现。在virtualenv实例中,os.py符号链接到virtualenv但是将编译直接导入virtualenv,这是dev_appserver使用的路径,有效阻止从系统python库访问任何模块与virtualend没有联系,大多数人都是这样。解决方案是“祝福”两条路径。

答案 1 :(得分:2)

谷歌AppEngine SDK为了将其安装引入sys.path而制作了很多技巧,而这些技巧依赖于实际文件的路径。我认为可能有很多种原因导致它失败。 SDK不会将自身安装为真正的python包,virtualenv不会完成沙盒,它只是设置一个环境(显然)并更改sys.path。而且GAE SDK也是这样做的,他们都认为,SDK正在快速发展并经常变化,所以这是一条非常坎坷的道路。

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

我的谈话时间有点迟了,但我遇到了同样的问题而且偶然发现了gae_installer,您可以使用pip install gae_installer以常规方式安装。{3}}。这会将谷歌应用引擎(gae)sdk直接放入你的python路径。希望其他人觉得这很有用。

答案 4 :(得分:0)

与博佐相同的答案。以下是说明:

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

  1. 在此处下载补丁:patch
  2. 将补丁移至 google_appengine / google / appengine / tools /
  3. 将您的工作目录更改为与上面相同的路径
  4. 类型: patch -p0&lt; dev_appserver.patch