Source code for aiohttp_mako
import functools
import sys
from collections.abc import Mapping
from aiohttp import web
from mako.lookup import TemplateLookup
from mako.exceptions import TemplateLookupException, text_error_template
__version__ = '0.4.0'
__all__ = ('setup', 'get_lookup', 'render_template', 'template',
'render_string')
APP_KEY = 'aiohttp_mako_lookup'
APP_CONTEXT_PROCESSORS_KEY = 'aiohttp_mako_context_processors'
REQUEST_CONTEXT_KEY = 'aiohttp_mako_context'
[docs]def setup(app, *args, app_key=APP_KEY, context_processors=(), **kwargs):
app[app_key] = TemplateLookup(*args, **kwargs)
if context_processors:
app[APP_CONTEXT_PROCESSORS_KEY] = context_processors
app.middlewares.append(context_processors_middleware)
return app[app_key]
[docs]def get_lookup(app, *, app_key=APP_KEY):
return app.get(app_key)
def render_string(template_name, request, context, *, app_key):
lookup = request.app.get(app_key)
if lookup is None:
raise web.HTTPInternalServerError(
text=("Template engine is not initialized, "
"call aiohttp_mako.setup(app_key={}) first"
"".format(app_key)))
try:
template = lookup.get_template(template_name)
except TemplateLookupException as e:
raise web.HTTPInternalServerError(
text="Template '{}' not found".format(template_name)) from e
if not isinstance(context, Mapping):
raise web.HTTPInternalServerError(
text="context should be mapping, not {}".format(type(context)))
if request.get(REQUEST_CONTEXT_KEY):
context = dict(request[REQUEST_CONTEXT_KEY], **context)
try:
text = template.render_unicode(**context)
except Exception: # pragma: no cover
exc_info = sys.exc_info()
errtext = text_error_template().render(
error=exc_info[1],
traceback=exc_info[2])
exc = MakoRenderingException(errtext).with_traceback(exc_info[2])
raise exc
return text
[docs]def render_template(template_name, request, context, *,
app_key=APP_KEY, encoding='utf-8'):
response = web.Response()
text = render_string(template_name, request, context, app_key=app_key)
response.content_type = 'text/html'
response.charset = encoding
response.text = text
return response
def template(template_name, *, app_key=APP_KEY, encoding='utf-8', status=200):
def wrapper(func):
@functools.wraps(func)
async def wrapped(*args):
context = await func(*args)
request = args[-1]
response = render_template(template_name, request, context,
app_key=app_key, encoding=encoding)
response.set_status(status)
return response
return wrapped
return wrapper
class MakoRenderingException(Exception):
"""Mako rendering exceptions with error """
@web.middleware
async def context_processors_middleware(request, handler):
request[REQUEST_CONTEXT_KEY] = {}
for processor in request.app[APP_CONTEXT_PROCESSORS_KEY]:
request[REQUEST_CONTEXT_KEY].update(await processor(request))
return await handler(request)
async def request_processor(request):
return {'request': request}