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

Luk*_*ncl 30 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文件来~/.virtualenv/foobar/lib/python2.5/site-packages/包含Google App Engine库:

/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
Run Code Online (Sandbox Code Playgroud)

(这是基于这个答案.)

然后我采购我的"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'
Run Code Online (Sandbox Code Playgroud)

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以尝试解决问题.

如果我python /usr/local/bin/dev_appserver.py使用virtualenv python 运行,问题仍然存在.如果我停用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
Run Code Online (Sandbox Code Playgroud)

boz*_*zzo 15

这是GAE SDK 的问题4339,已经确认,并且bug条目中有两个稍微不同的补丁可以使它工作.

所发生的是dev_appserver.py通过禁止访问任何非system-python模块来设置受限制的python环境,并通过从os模块的位置计算系统python文件夹来实现.在virtualenv实例中,它os.py被符号链接到virtualenv中,但是直接编译成virtualenv,这是dev_appserver使用的路径,有效地阻止了对系统python库中任何未被virtualend链接的模块的访问,而virtualend就是其中的大多数.解决方案是"祝福"两条路径.