Skip to content

Instantly share code, notes, and snippets.

@szeyu
Last active May 7, 2026 05:49
Show Gist options
  • Select an option

  • Save szeyu/623096fb6462e633e2714ba912adc8f3 to your computer and use it in GitHub Desktop.

Select an option

Save szeyu/623096fb6462e633e2714ba912adc8f3 to your computer and use it in GitHub Desktop.
Converting Jupyter Notebook to PDF

Export Jupyter Notebook to PDF

Use nbconvert[webpdf] to export a Jupyter notebook to PDF without LaTeX.

Option 1: Simple and Reliable

This lets Playwright download its own Chromium if needed.

#!/usr/bin/env bash
set -e

uvx --from "nbconvert[webpdf]" jupyter-nbconvert \
  --to webpdf \
  --allow-chromium-download \
  "$1"

Usage:

bash notebook_to_pdf.sh your_notebook.ipynb

Option 2: No Chromium Download

Use this if Chromium is already installed and you do not want Playwright to download another copy.

#!/usr/bin/env bash
set -e

# Find installed Chromium/Chrome. Override if needed:
# CHROMIUM_PATH=/path/to/chromium bash notebook_to_pdf.sh notebook.ipynb
CHROMIUM_PATH="${CHROMIUM_PATH:-$(command -v chromium-browser || command -v chromium || command -v google-chrome || true)}"

if [ -z "$CHROMIUM_PATH" ]; then
  echo "Error: Chromium/Chrome not found. Set CHROMIUM_PATH=/path/to/chromium."
  exit 1
fi

# Temporary Playwright browser directory.
PW_PATH="/tmp/ms-playwright"

# Get the Chromium revision expected by the current Playwright package.
REVISION="$(uvx --from "playwright" python -c 'import json, pathlib, playwright; d=pathlib.Path(playwright.__file__).parent / "driver" / "package" / "browsers.json"; print([b["revision"] for b in json.loads(d.read_text())["browsers"] if b["name"]=="chromium-headless-shell"][0])')"

# Create the browser path Playwright expects, but point it to system Chromium.
mkdir -p "$PW_PATH/chromium_headless_shell-$REVISION/chrome-headless-shell-linux64"
ln -sf "$CHROMIUM_PATH" \
  "$PW_PATH/chromium_headless_shell-$REVISION/chrome-headless-shell-linux64/chrome-headless-shell"

# TMPDIR beside the notebook helps snap Chromium access nbconvert's temporary HTML.
PLAYWRIGHT_BROWSERS_PATH="$PW_PATH" \
TMPDIR="$(dirname "$1")" \
uvx --from "nbconvert[webpdf]" jupyter-nbconvert \
  --to webpdf \
  --disable-chromium-sandbox \
  --WebPDFExporter.allow_chromium_download=False \
  "$1"

TMPDIR="$(dirname "$1")" helps when using snap Chromium, because it may not be able to access temporary files in /tmp.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment