【问题标题】:Cannot use jinja2 PackageLoader on Google App Engine无法在 Google App Engine 上使用 jinja2 PackageLoader
【发布时间】:2013-03-26 10:32:47
【问题描述】:

我正在尝试使用 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 时,在 Google App Engine 中,provider 始终是 NullProvider。当我手动请求提供者时,我得到一个DefaultProvider,所以很明显这里出了点问题。

要请求提供者,我通过转到该目录来确保 lib/somepackagesys.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)上运行。

【问题讨论】:

  • 我没有仔细看你的问题,但 jinja2 用于样板,可能会帮助github.com/coto/gae-boilerplate
  • @peterretief 我查看了gae-boilerplate 项目,但找不到PackageLoader 的任何用法。不过还是谢谢 ;-)

标签: python google-app-engine jinja2


【解决方案1】:

我认为问题出在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 上有效。

【讨论】:

  • 查看各种链接,似乎此问题已在 1.2.1 中修复。但是我在 1.7.5 上遇到了这个问题,它不应该有这个问题。你在 1.7.5 上运行了吗?
  • 要回答您的问题,是的,commoncommon.templates 中有一个 __init__.py。 ;-)
猜你喜欢
  • 1970-01-01
  • 2011-01-22
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 2011-03-06
  • 2012-06-06
  • 1970-01-01
  • 2014-01-20
相关资源
最近更新 更多