Martin's answer gives a good explanation of the reasons for this error.
The accepted answer fixes the problem posed, but this, of course, is not the only way. In my case, I had something more:
import threading from flask import Flask, render_template app = Flask("myapp") app.route('/') def get_thing(thing_id): thing = cache.get(thing_id) if thing is None:
But when get_thing_from_datastore_render_and_cache_it running in the background thread outside the jar request loop, I got the error shown above because this thread did not have access to the request context.
The error arises because Flask offers a shortcut for developers to automatically access query variables in the template - in other words, this is caused by Flask's decisions on how to wrap Jinja2 and not Jinja2 functionality. My approach to solving this issue was to use Jinja2 directly:
import jinja2 def render_without_request(template_name, **template_vars): """ Usage is the same as flask.render_template: render_without_request('my_template.html', var1='foo', var2='bar') """ env = jinja2.Environment( loader=jinja2.PackageLoader('name.ofmy.package','templates') ) template = env.get_template(template_name) return template.render(**template_vars)
This feature assumes that your Flask application has a traditional template subfolder. In particular, the project structure will be here
. βββ name/ βββ ofmy/ | βββ package/ | | βββ __init__.py <--- Where your Flask application object is defined | | βββ templates/ | | βββ my_template.html | βββ __init__.py βββ __init__.py
If you have a subdirectory structure in templates/ , you simply pass the relative path from the root of the templates folder in the same way as when using Flask render_template .
source share