What is the proper way to specify a custom template path for nbconvert?
Under nbonvert version 6, templates are now a directory with several files. Those templates can live in any number of locations depending on the platform.
Raspbian:
['/home/pi/.local/share/jupyter/nbconvert/templates', '/usr/local/share/jupyter/nbconvert/templates', '/usr/share/jupyter/nbconvert/templates']
OS X with Pyenv:
['/Users/ac/Library/Jupyter/nbconvert/templates', '/Users/ac/.pyenv/versions/3.8.5/Python.framework/Versions/3.8/share/jupyter/nbconvert/templates', '/usr/local/share/jupyter/nbconvert/templates', '/usr/share/jupyter/nbconvert/templates']
I'm trying to sync my templates over several different platforms and would like to specify a custom location.
This post from 2 years ago seems correct, but appears to apply to V5 of nbconvert -- the method has changed names from template_path
to template_paths
.
I've tried the solution suggested in the link above using a template that I know works when placed in one of the known locations. I end up with this error when trying to specify a custom location as suggested:
jinja2.exceptions.TemplateNotFound: null.j2
I suspect that by setting the path to /path/to/.jupyter/templates/my_template/
, I completely override all the other template locations and lose the null.j2
template that my template extends. I've included my template at the end on the off chance it has some errors that are causing this.
The docs for V6 config files are not much help either:
TemplateExporter.template_paths : List
Default: ['.']
No description
and
PythonExporter.template_paths : List
Default: ['.']
No description
There's a long thread from May 2019 discussing this on the Git Repo, but I can't quite make sense of what the ultimate conclusion was.
My custom Python template:
{%- extends 'null.j2' -%}
## set to python3
{%- block header -%}
#!/usr/bin/env python3
# coding: utf-8
{% endblock header %}
## remove cell counts entirely
{% block in_prompt %}
{% if resources.global_content_filter.include_input_prompt -%}
{% endif %}
{% endblock in_prompt %}
## remove markdown cells entirely
{% block markdowncell %}
{% endblock markdowncell %}
{% block input %}
{{ cell.source | ipython2python }}
{% endblock input %}
## remove magic statement completely
{% block codecell %}
{{'' if "get_ipython" in super() else super() }}
{% endblock codecell%}
Issue #1428 on the Git Repo contains the basis for this solution.
From scratch/recent upgrade from v5 to v6 do the following:
~/.jupyter
$ jupyter nbconvert --generate-config
~/.jupyter/jupyter_nbconvert_config.py
to add the following lines:from pathlib import Path
# set a custom path for templates in
c.TemplateExporter.extra_template_basedirs
my_templates = Path('~/my/custom/templates').expanduser().absolute()
# add the custom path to the extra_template_basedirs
c.TemplateExporter.extra_template_basedirs = [my_templates]
Add templates to the ~/my/custom/templates
directory
/my/custom/templates/foo_template
)conf.json
and index.py.j2
file. the index is the actual template. See below for an examplerun nbconvert:
$ jupyter nbconvert --to python --template my_custom_template foo.ipynb
conf.json
Basic Example
{
"base_template": "base",
"mimetypes": {
"text/x-python": true
}
}
index.py.j2
Example
{%- extends 'null.j2' -%}
## set to python3
{%- block header -%}
#!/usr/bin/env python3
# coding: utf-8
{% endblock header %}
## remove cell counts entirely
{% block in_prompt %}
{% if resources.global_content_filter.include_input_prompt -%}
{% endif %}
{% endblock in_prompt %}
## remove markdown cells entirely
{% block markdowncell %}
{% endblock markdowncell %}
{% block input %}
{{ cell.source | ipython2python }}
{% endblock input %}
## remove magic statement completely
{% block codecell %}
{{'' if "get_ipython" in super() else super() }}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With