A framework for building print media with nbconvert.
Install with pip:
pip install nbprintInstall with conda
conda install nbprint -c conda-forgeJupyter Notebooks are widely used for reports via nbconvert. Most efforts focus on building web reports / websites from notebooks, including Voilà and Jupyter Book.
Despite being the primary goal of early notebook conversion efforts, in recent years much less focus has been spent on print media - PDFs for reports, academic papers, newspapers, etc. There are many examples of nbconvert templates for academic papers, as well as projects like ipypublish. Most of these efforts focus on nbprint itself started as convenience framework for formatting charts and tables similarly between html and pdf outputs.
However, with recent releases to nbconvert, which now supports webpdf (printing as pdf from within a headless web browser), and with advances to the @media print CSS directive spearheaded by the lovely folks at pagedjs, it is now much easier to build publication ready print-oriented media on the web.
This is the goal of nbprint. Using pagedjs, nbprint provides templates and utilities for building web reports targeting print media. Beyond that, it provides infrastructure for parameterizing and configuring documents via pydantic, which makes designing and generating reports a breeze, even without knowledge of Python. Documents are modular and can be easily composed via hydra.
nbprint provides an nbconvert template and a configuration framework.
The simplest example can be run with defaults by calling the nbprint executable on an existing notebook:
nbprint examples/basic.ipynbThis CLI supports configuration-driven customization with hydra syntax:
nbprint examples/basic.ipynb +name=test ++outputs.target=pdfgraph TB
nb("notebook<br>(.ipynb)")
nbc{nbconvert}
nbct[/nbprint <br> template/]
pjs[/paged.js <br> layout engine/]
o@{ shape: doc, label: "output (html,pdf,etc)" }
nb e2@--->nbc
e2@{animate: true}
nbct --> nbc
pjs --- nbct
nbc e3@-->o
e3@{animate: true}
nbprint can be used purely via notebook metadata, but it also provides a yaml-based framework for configuration (via pydantic, hydra, and omegaconf).
This is particularly convenient when generating parameterized or componentized reports.
graph TB
subgraph Config Framework
yml("configuration<br>(.yaml)")
pg[plugins<br> via hydra]
lb[python<br>libraries]
pg -.- yml
lb -.- yml
end
nb("notebook<br>(.ipynb)")
nbc{nbconvert}
nbct[/nbprint <br> template/]
pjs[/paged.js <br> layout engine/]
o@{ shape: doc, label: "output (html,pdf,etc)" }
yml e1@--->nb
e1@{animate: true}
nb e2@--->nbc
e2@{animate: true}
nbct --> nbc
pjs --- nbct
nbc e3@-->o
e3@{animate: true}
For example, imagine I had a collection of models that I wanted to evaluate for different hyperparameters, where models might have overlapping sets of report elements I want to see.
With nbprint's configuration system, this is easy to compose.
graph TB
subgraph Report C
p1[Params Three]
m4[Content One]
m5[Content Three]
end
subgraph Report B
p2[Params Two]
m1[Content One]
m2[Content Two]
m3[Content Three]
end
subgraph Report A
p3[params One]
m6[Content Two]
m7[Content Three]
end
This configuration also allows for easier iteration on a report's design and content.
Let's take a simple placeholder report.
---
debug: false
outputs:
_target_: nbprint:NBConvertOutputs
path_root: ./examples/output
target: "html"
content:
- _target_: nbprint:ContentMarkdown
content: |
# A Generic Report
## A Subtitle
css: ":scope { text-align: center; }"
- _target_: nbprint:ContentPageBreak
- _target_: nbprint:ContentTableOfContents
- _target_: nbprint:ContentPageBreak
- _target_: nbprint:ContentMarkdown
content: |
# Section One
Lorem ipsum dolor sit amet.
## Subsection One
Consectetur adipiscing elit, sed do eiusmod tempor incididunt.
## Subsection Two
Ut labore et dolore magna aliqua.
- _target_: nbprint:ContentPageBreak
- _target_: nbprint:ContentFlexRowLayout
sizes: [1, 1]
content:
- _target_: nbprint:ContentFlexColumnLayout
content:
- _target_: nbprint:ContentMarkdown
content: |
# Section Two
Lorem ipsum dolor sit amet.
## Subsection One
Consectetur adipiscing elit, sed do eiusmod tempor incididunt.
- _target_: nbprint:ContentFlexColumnLayout
content:
- _target_: nbprint:ContentMarkdown
content: |
# Section Three
Ut labore et dolore magna aliqua.
## Subsection One
Ut enim ad minim veniam, quis nostrud.Let's break this down step by step.
First, we configure debug: false. This tells nbprint to run pagedjs print preview. We also set the output to run nbconvert and configure the folder for outputs to be placed.
Next we fill in some content. Here we use a few components:
ContentMarkdownto generate Markdown cellsContentPageBreakto split onto a new page in our pdfContentTableOfContentsto create a table of contents. Note that this will work in both html preview, and pdf form!ContentFlexRowLayoutandContentFlexColumnLayoutto create some layout structure for our document.
We can now generate the report by running the CLI:
nbprint examples/basic.yamlThis will create a Notebook output in our specified folder examples/output, as well as an html asset (since that is what we specified in the yaml file). Both will have the date as a suffix, which is also configurable in our yaml. We see the generated report notebook, which we can open and use for further experimentation or to investigate the report itself.
We also see the html document itself, which will be rendered via pagedjs print preview.
You can find a pdf form of this document here.
Warning: This project is under active development, so all APIs are subject to change!
- nbconvert: Convert Notebooks to other formats
- pagedjs: Paged.js is a free and open-source library that paginates any HTML content to produce beautiful print-ready PDF
- Voilà: Voilà turns Jupyter notebooks into standalone web applications
- Jupyter Book: Build beautiful, publication-quality books and documents from computational content
- ipypublish: A workflow for creating and editing publication ready scientific reports and presentations, from one or more Jupyter Notebooks, without leaving the browser!
Additionally, this project relies heavily on:
- pydantic: Pydantic is the most widely used data validation library for Python.
- hydra: Hydra is a framework for dynamically creating hierarchical configuration by composition, with the ability to override through config files and the command line
- omegaconf: OmegaConf is a hierarchical configuration system, with support for merging configurations from multiple sources
- typer: Typer is a library for building CLI applications based on Python type hints
This software is licensed under the Apache 2.0 license. See the LICENSE file for details.
Note
This library was generated using copier from the Base Python Project Template repository.

