Notebooks become reports and scheduled jobs only when they can be executed and exported without a person clicking.
nbconvert turns a notebook into other formats:
jupyter nbconvert --to html report.ipynb # shareable, keeps outputs
jupyter nbconvert --to script analysis.ipynb # .py file of the code cells
jupyter nbconvert --to webpdf report.ipynb # PDF via a headless browser--execute runs all cells top to bottom in a fresh kernel before converting, which both refreshes outputs and proves the notebook works from scratch. Add --ExecutePreprocessor.timeout=600 for long cells, and --no-input to hide code and show only results, a common way to publish reports for non-programmers. --to notebook --inplace --execute updates the notebook itself.
papermill adds parameters: tag one cell parameters (cell toolbar > tags) containing defaults such as region = "eu". Then
papermill report.ipynb out/report_us.ipynb -p region us -p year 2026injects a new cell after it with the given values, executes the notebook and saves the result, with outputs, as a new notebook. Failed cells are highlighted in the output notebook, which makes it an excellent execution log. It also has a Python API, papermill.execute_notebook, useful in Airflow or other schedulers.
Under both tools sits nbclient, which starts a kernel and runs cells. For production pipelines, keep notebooks for exploration and reporting, and move reusable logic into importable .py modules that the notebook calls.
Example
# report.ipynb has a cell tagged "parameters": region = "eu"; year = 2025
jupyter nbconvert --to html --execute --no-input report.ipynb
# [NbConvertApp] Writing ... bytes to report.html
jupyter nbconvert --to script report.ipynb # -> report.py
papermill report.ipynb out/report_us.ipynb -p region us -p year 2026
# Executing notebook with kernel: python3
# (out/report_us.ipynb gets an injected cell: region = "us", year = 2026)
python - <<'EOF'
import papermill as pm
pm.execute_notebook("report.ipynb", "out/report_jp.ipynb",
parameters={"region": "jp"})
EOFRemember
jupyter nbconvert --to html|script|webpdfexports;--executereruns first--no-inputpublishes results without code- papermill injects parameters into a tagged cell and saves an executed copy
Watch out for
- Exporting a notebook without
--execute, shipping stale outputs that the current code would not produce.