Rendering Templates with Jinja 2 Does Not Work
agentS opened this issue · comments
Hi,
First of all thank you for your great library, I really appreciate your effort.
I am having an issue with testing a function which calls Flask's render_template
function. Whenever executing the command pytest
the error shown below is thrown.
def test_generate_notebook_for_experiment():
> notebook = generate_notebook_for_experiment(constants.EXPERIMENT_CONFIG)
test\jupyterlab\jupyter_hub_test.py:16:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
jupyterlab\jupyter_hub.py:31: in generate_notebook_for_experiment
import_code = render_template(f'{TEMPLATE_FOLDER}/imports.pytemplate', configuration = notebook_configuration)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
template_name_or_list = 'notebook/imports.pytemplate'
context = {'configuration': {'collections': {'edge_collections': {'BNL_data_juvnf6wv': 'pcbs_local_BNL_data_juvnf6wv_data_edges'...': 'gduser@Siemens', 'port': 8080, ...}, 'graphname': 'pcbs_local', 'module': 'gdf.contrib.managers.ArangoDBManager'}}}
ctx = None
def render_template(template_name_or_list, **context):
"""Renders a template from the template folder with the given
context.
:param template_name_or_list: the name of the template to be
rendered, or an iterable with template names
the first one existing will be rendered
:param context: the variables that should be available in the
context of the template.
"""
ctx = _app_ctx_stack.top
> ctx.app.update_template_context(context)
E AttributeError: 'NoneType' object has no attribute 'app'
The following snippet shows the method to be tested, which invokes the render_template
function.
from nbformat.v4 import new_notebook, new_code_cell, new_markdown_cell
from nbformat import NotebookNode
from flask import Flask, render_template
def generate_notebook_for_experiment(notebook_configuration: Dict) -> NotebookNode:
"""Create a new Jupyter notebook with template code for the specified experiment."""
TEMPLATE_FOLDER = 'notebook'
title = new_markdown_cell('# Experiment Notebook')
import_code = render_template(f'{TEMPLATE_FOLDER}/imports.pytemplate', configuration = notebook_configuration)
import_code_cell = new_code_cell(import_code, metadata = __create_metadata_for_hidden_cell__())
notebook = new_notebook(
cells=[ title, import_code_cell ],
...
)
return notebook
This is the complete test method causing the error:
def test_generate_notebook_for_experiment():
notebook = generate_notebook_for_experiment(constants.EXPERIMENT_CONFIG)
assert notebook.nbformat == 4
nbformat.validate(nbjson=notebook, version=4, version_minor=2)
My code for creating the fixture is shown below.
import pytest
from gdrest.application import create_app
@pytest.fixture
def app():
app, _ = create_app()
return app
What do I need to do to make sure the Jinja2 runtime environment is appropriately configured by Flask so the function render_template
is safe to execute? Thank you so much for your answers!
Hi there @agentS. I believe this isn't a pytest-flask related issue, but rather a question about Flask. Flask works with application contexts and the render_template method requires such a context. Lets go through the more relevant lines in your traceback:
ctx = _app_ctx_stack.top # <<< this tries to fetch the topmost context from stack
ctx.app.update_template_context(context) # <<< this will fail since ctx = None
flask.templating.render_template implementation for the curious ones
So this is happening because render_template
is being called from "outside" a valid flask application context. Finally, stack overflow would probably be better suited for questions of this nature considering the issue tracker is a tool to address bugs and feature requests in pytest-flask itself.