Хобрук: Ваш путь к мастерству в программировании

Невозможно использовать jinja2 PackageLoader в Google App Engine

Я пытаюсь использовать PackageLoader jinja2, но не могу заставить его работать.

В моем 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-файл содержит только текст «тест».

Когда создается PackageLoader, provider всегда равно NullProvider в Google App Engine. Когда я вручную запрашиваю поставщика, я получаю 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, это работает, однако, я думаю, это не сработает в почтовом индексе:

import common.templates
env = Environment(loader=FileSystemLoader(common.templates.__path__))

Я видел этот вопрос SO, но это не проблема.

Обновление:

Я только что протестировал пример в SDK 1.7.6, и он работает, однако мне бы хотелось, чтобы он работал на более старом SDK (или на сервере old_dev_appserver).


  • Я не разбирался в вашем вопросе, но jinja2 используется в шаблоне, может помочь github.com/coto/ гей-шаблон 02.04.2013
  • @peterretief Я просмотрел проект gae-boilerplate, но не нашел никакого использования PackageLoader. Но все равно спасибо ;-) 03.04.2013

Ответы:


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 в движке приложений Google

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.

01.04.2013
  • Глядя на различные ссылки, кажется, что эта проблема была исправлена ​​в 1.2.1. Однако я столкнулся с этой проблемой на 1.7.5, у которой не должно быть этой проблемы. У тебя получилось на 1.7.5? 02.04.2013
  • Чтобы ответить на ваш вопрос, да, есть __init__.py в common и в common.templates. ;-) 03.04.2013
  • Новые материалы

    Создание успешной организации по науке о данных
    "Рабочие часы" Создание успешной организации по науке о данных Как создать эффективную группу по анализу данных! Введение Это обзорная статья о том, как создать эффективную группу по..

    Технологии и проблемы будущей работы
    Изучение преимуществ и недостатков технологий в образовании В быстро меняющемся мире технологии являются решающим фактором в формировании будущего работы. Многие отрасли уже были..

    Игорь Минар из Google приедет на #ReactiveConf2017
    Мы рады сообщить еще одну замечательную новость: один из самых востребованных спикеров приезжает в Братиславу на ReactiveConf 2017 ! Возможно, нет двух других кланов разработчиков с более..

    Я собираюсь научить вас Python шаг за шагом
    Привет, уважаемый энтузиаст Python! 👋 Готовы погрузиться в мир Python? Сегодня я приготовил для вас кое-что интересное, что сделает ваше путешествие более приятным, чем шарик мороженого в..

    Альтернатива шаблону исходящих сообщений для архитектуры микросервисов
    Познакомьтесь с двухэтапным сообщением В этой статье предлагается альтернативный шаблон для папки Исходящие : двухэтапное сообщение. Он основан не на очереди сообщений, а на..

    React on Rails
    Основное приложение Reverb - это всеми любимый монолит Rails. Он отлично обслуживает наш API и уровень просмотра трафика. По мере роста мы добавляли больше интерактивных элементов..

    Что такое гибкие методологии разработки программного обеспечения
    Что представляют собой гибкие методологии разработки программного обеспечения в 2023 году Agile-методологии разработки программного обеспечения заключаются в следующем: И. Введение A...