¿Cuál es el método preferido para usar jinja2 en App Engine?

Originalmente implementé Jinja2 en App Engine usando los ejemplos que se muestran en el sitio de App Engine aquí: https://developers.google.com/appengine/docs/python/gettingstartedpython27/templates donde jinja2 se importa directamente:

import jinja2 import os jinja_environment = jinja2.Environment( loader=jinja2.FileSystemLoader(os.path.dirname(__file__))) class MainPage(webapp2.RequestHandler): def get(self): greetings = 'somestring' template_values = { 'greetings': greetings, } template = jinja_environment.get_template('index.html') self.response.out.write(template.render(template_values)) 

Pero actualmente estoy trabajando en Simpleauth ( https://github.com/crhym3/simpleauth ) que sigue la implementación que Nick Johnson describió aquí: http://blog.notdot.net/2011/11/Migrating-to-Python -2-7-part-2-Webapp-and-templates donde jinja2 se importa desde webapp2_extras:

 import os import webapp2 from webapp2_extras import jinja2 class BaseHandler(webapp2.RequestHandler): @webapp2.cached_property def jinja2(self): return jinja2.get_jinja2(app=self.app) def render_template(self, filename, **template_args): self.response.write(self.jinja2.render_template(filename, **template_args)) class IndexHandler(BaseHandler): def get(self): self.render_template('index.html', name=self.request.get('name')) 

¿Cuál de estos es el método preferido para usar jinja2? (No parecen jugar muy bien juntos, y preferirían estandarizar la mejor opción).

Supongo que son casi lo mismo. Lo que webapp2_extras.jinja2 hace además es que almacena en caché la inicialización de jinja2.Environment () (para la duración de la solicitud). Además, puede aprovechar el sistema de configuración / registro de la aplicación web2.

Si observa la fuente get_jinja2 () verá que es solo un contenedor práctico para jinja2.Environment () con algunos argumentos de entorno predeterminado y extensiones habilitadas (por ejemplo, i18n).

Tenía la misma pregunta, pero las respuestas aquí no me satisfacen.

Creo que se trata de encapsulación vs rendimiento. Para una aplicación pequeña puedes tener un global, no hay problema. Así que la primera solución está bien. Le permite resolver un problema fácil de una manera fácil, sin la sobrecarga para aprender los detalles de un marco.

Para una aplicación más grande, probablemente le guste encapsular y poner algo de orden en sus objetos. Básicamente se hace un framework, una infraestructura para escalabilidad. Pero eso es lo que se supone que webapp2 te da.

El problema básico detrás de esto: si decides hacer un tipo de objeto singleton local para una clase que se instancia y libera como parte de la lógica (como las clases webapp2.RequestHandler en ejemplos oficiales), entonces ese objeto referenciado (jinja2) será liberado cuando la última instancia de clase se ha ido … puede obtener mucha liberación y reasignación. Por lo tanto, es bueno tener un enlace a un objeto en algún lugar (webapp2.registry) para evitar la eliminación, incluso si no se hace referencia en ningún otro lugar. Es como global, pero sin contaminar el espacio de nombres global, y es accesible desde cualquier lugar a través del registro webapp2.get_app (). También es el almacenamiento en caché. Luego, con cached_property usted hace solo otra capa de almacenamiento en caché.

En resumen: si desea encapsular, es mejor agregar almacenamiento en caché para que su aplicación sea eficiente

En este caso, vaya para webapp2_extra jinja2 y en cada módulo puede acceder al mismo entorno jinja con:

 jinja2.get_jinja2().environment 

El primer método es un ejemplo muy básico.

El segundo (con el BaseHandler) es el método preferido. Aquí pones los métodos compartidos webapp2. Estos métodos pueden ser utilizados por clases derivadas y aquí usted coloca los métodos webapp2 que desea anular como despacho.

TL; DR: Utilice la opción # 2

Si no usas i18n, entonces no importa mucho. Pero en el mundo real la gente habla diferentes idiomas que el inglés, y hay un problema complicado con jinja2 i18n en GAE: Threading (es decir, threadsafe: true en app.yaml) está activado de forma predeterminada y es importante para el rendimiento, pero la mayoría de los documentos i18n de jinja2 Usted puede encontrar en la web no son seguros para subprocesos. Dado que no desea pasar explícitamente la configuración regional a cada macro jinja2, debe mantenerse en una variable de subproceso local. Esto es lo que webapp2_extras.jinja2 hace correctamente.