我正在尝试使用 jinja2 提供的 PackageLoader,但我无法让它工作。
在我的 app.yaml
中,我声明了所需的库:
libraries:
- name: jinja2
version: latest
- name: setuptools
version: latest
我可以创建的最小示例:
import webapp2, sys
from jinja2 import Environment, PackageLoader
sys.path += ['lib/somepackage']
class Test(webapp2.RequestHandler):
def get(self):
env = Environment(loader=PackageLoader('common'))
self.response.write(env.get_template('test.html').render())
routes = [(r"/", Test)]
app = webapp2.WSGIApplication(routes, debug=True)
包 common
存在于目录 lib/somepackage
中,并且有一个包 templates
,其中包含一个文件 test.html
。 html 文件仅包含文本“test”。
PackageLoader
构建时,它的 provider
在 Google App Engine 中始终是 NullProvider
。当我手动请求提供者时,我得到了一个 DefaultProvider
,所以显然这里出了点问题。
为了请求提供者,我确保 lib/somepackage
位于 sys.path
中,方法是转到该目录,然后:
>>> import pkg_resources
>>> provider = pkg_resources.get_provider('common')
>>> provider
<pkg_resources.DefaultProvider instance at 0x8490b2c>
当这在 Google App Engine 中失败时,这是回溯的相关部分:
File "/<>/test/main.py", line 7, in get
self.response.write(env.get_template('test.html').render())
File "/<>/google_appengine/lib/jinja2-2.6/jinja2/environment.py", line 719, in get_template
return self._load_template(name, self.make_globals(globals))
File "/<>/google_appengine/lib/jinja2-2.6/jinja2/environment.py", line 693, in _load_template
template = self.loader.load(self, name, globals)
File "/<>/google_appengine/lib/jinja2-2.6/jinja2/loaders.py", line 115, in load
source, filename, uptodate = self.get_source(environment, name)
File "/<>/google_appengine/lib/jinja2-2.6/jinja2/loaders.py", line 226, in get_source
if not self.provider.has_resource(p):
File "/<>/google_appengine/lib/setuptools-0.6c11/pkg_resources.py", line 1170, in has_resource
return self._has(self._fn(self.module_path, resource_name))
File "/<>/google_appengine/lib/setuptools-0.6c11/pkg_resources.py", line 1218, in _has
"Can't perform this operation for unregistered loader type"
NotImplementedError: Can't perform this operation for unregistered loader type
当我使用 FileSystemLoader
时它可以工作,但是我猜这在 zip 中不起作用:
import common.templates
env = Environment(loader=FileSystemLoader(common.templates.__path__))
我看过this SO question但这不是问题。
更新:
我刚刚在 1.7.6 SDK 中测试了这个示例并且它可以工作,但是我希望看到它在旧的 SDK(或 old_dev_appserver)上工作。
最佳答案
我认为问题在于 pkg_resources
。
一些 os
相关功能没有在 GAE 中实现,但 jinja2 或 Google 似乎提供了解决方法。
这些链接说明了这个问题:
http://code.google.com/p/googleappengine/issues/detail?id=60
https://github.com/mitsuhiko/jinja2/issues/143
Jinja2 PackageLoader on google app engine
https://bitbucket.org/tarek/distribute/issue/73/pkg_resources-fails-on-google-app-engine
我用过
jinja_environment = jinja2.Environment(autoescape=True,
loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
作为样板,从与设置定义的文件相同的目录中的“template
”目录中获取模板。但问题是关于压缩为 eggs
并使用 PackageLoader
程序包中是否有 __init__.py
文件? 不过你说它适用于 1.7.6。
关于python - 无法在 Google App Engine 上使用 jinja2 PackageLoader,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15634836/