jupyter / nbconvert

Jupyter Notebook Conversion
https://nbconvert.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
1.73k stars 565 forks source link

"style.css" not found when inheriting from classic template #1858

Open jhancke opened 2 years ago

jhancke commented 2 years ago

Using nbconvert from the code, there is an error when inheriting from the classic template, stating that the static/style.css can't be found.

The custom template was put beside the other templates in /usr/local/share/jupyter/nbconvert/templates It contains a .conf file stating that the base template is classic and a template including {%- extends 'classic/index.html.j2' -%}

When converting the notebook by calling html_exporter.from_notebook_node(notebook) the error is thrown:

...
"  File \"/usr/local/lib/python3.9/site-packages/nbconvert/exporters/templateexporter.py\", line 402, in from_notebook_node\n    output = self.template.render(nb=nb_copy, resources=resources)\n", 
"  File \"/usr/local/lib/python3.9/site-packages/jinja2/environment.py\", line 1304, in render\n    self.environment.handle_exception()\n", 
"  File \"/usr/local/lib/python3.9/site-packages/jinja2/environment.py\", line 925, in handle_exception\n    raise rewrite_traceback_stack(source=source)\n",
"  File \"/usr/local/share/jupyter/nbconvert/templates/custom/index.html.j2\", line 1, in top-level template code\n    {%- extends 'classic/index.html.j2' -%}\n", 
"  File \"/usr/local/share/jupyter/nbconvert/templates/classic/index.html.j2\", line 3, in top-level template code\n    {% from 'jupyter_widgets.html.j2' import jupyter_widgets %}\n", 
"  File \"/usr/local/share/jupyter/nbconvert/templates/lab/base.html.j2\", line 2, in top-level template code\n    {% from 'celltags.j2' import celltags %}\n", 
"  File \"/usr/local/share/jupyter/nbconvert/templates/base/display_priority.j2\", line 1, in top-level template code\n    {%- extends 'base/null.j2' -%}\n",
"  File \"/usr/local/share/jupyter/nbconvert/templates/base/null.j2\", line 24, in top-level template code\n    {%- block header -%}\n", 
"  File \"/usr/local/share/jupyter/nbconvert/templates/custom/index.html.j2\", line 7, in block 'header'\n    {%- block html_head -%}\n", 
"  File \"/usr/local/share/jupyter/nbconvert/templates/custom/index.html.j2\", line 8, in block 'html_head'\n    {{ super() }}\n", 
"  File \"/usr/local/share/jupyter/nbconvert/templates/classic/index.html.j2\", line 36, in block 'html_head'\n    {% block notebook_css %}\n", 
"  File \"/usr/local/share/jupyter/nbconvert/templates/classic/index.html.j2\", line 37, in block 'notebook_css'\n    {{ resources.include_css(\"static/style.css\") }}\n", 
"  File \"/usr/local/lib/python3.9/site-packages/nbconvert/exporters/html.py\", line 228, in resources_include_css\n    code = \"\"\"<style type=\"text/css\">\\n%s</style>\"\"\" % (env.loader.get_source(env, name)[0])\n",
"  File \"/usr/local/lib/python3.9/site-packages/jinja2/loaders.py\", line 544, in get_source\n    raise TemplateNotFound(template)\n", "jinja2.exceptions.TemplateNotFound: static/style.css\n"]}

Nbconvert version: 7.0

jhancke commented 2 years ago

I made up a minimal example to reproduce this error. I have a template custom which lives in /usr/local/share/jupyter/nbconvert/templates/custom: custom/ -- conf.json -- index.html.j2

conf.json

{
  "base_template": "classic",
  "mimetypes": {
    "text/html": true
  },
  "preprocessors": {
    "100-pygments": {
      "type": "nbconvert.preprocessors.CSSHTMLHeaderPreprocessor",
      "enabled": true,
      "style": "default"
    }
  }
}
{%- extends 'classic/index.html.j2' -%}

{% block footer %}
FOOOOOOOOTEEEEER
{% endblock footer %}

Some code to convert notebooks:

import json
from nbconvert import HTMLExporter
import nbformat

class MyExporter(HTMLExporter):
    template_file = 'custom/index.html.j2'

def read_notebook(path):
    with open(path) as json_file:
        data = json_file.read()
    json_body = json.loads(data)
    return nbformat.reads(json.dumps(json_body), 4)

if __name__ == '__main__':
    path = ''
    notebook = read_notebook(path)
    my_exporter = MyExporter()
    (body, resources) = my_exporter.from_notebook_node(notebook)
    print(body)

I also tried using classic template directly:

class MyExporter(HTMLExporter):
    template_file = 'classic/index.html.j2'

Which also fails with the same error.

I also found out that when using template_name=classic or template_name=custom the issue does not happen.

mpharrigan commented 1 year ago

this could be related: https://github.com/jupyter/nbconvert/pull/1827

rasquith commented 1 year ago

How was this issue resolved?