Skip to main content

A smooth local reader for saved Jupyter notebooks with lazy media output streaming.

Project description

ipynb-local-viewer

PyPI Python License: MIT CI

A smooth, local-first reader for saved Jupyter notebooks.

ipynb-local-viewer turns an .ipynb file into a fast reading surface: markdown headings become an outline, outputs are shown first, code is collapsed behind syntax-highlighted expandable blocks, and large images or videos are loaded through lazy streamed asset URLs instead of being embedded into the main page payload.

In normal viewing mode it reads saved notebooks only and does not execute code. Packaged demo notebooks can be executed explicitly with the optional [demo] extra.

Features

  • Markdown-derived outline with smooth section navigation.
  • Lazy image and video output loading for media-heavy notebooks.
  • Collapsed code cells with Pygments syntax highlighting.
  • Safe sanitized HTML output rendering with Bleach.
  • Light, dark, and device theme modes.
  • Local Flask server with no frontend build step.
  • Root-restricted notebook access for safer local browsing.
  • Small decoded media cache for faster repeat reads.
  • Optional live demo notebooks with scientific and visualization outputs.

Install

python -m pip install ipynb-local-viewer

Install the optional demo stack when you want to run the packaged examples:

python -m pip install "ipynb-local-viewer[demo]"

For local development from a checkout:

python -m pip install -e ".[demo]"

Quick Start

Open a notebook on http://localhost:8770:

notebook-viewer --notebook analysis.ipynb --port 8770

Restrict the viewer to a specific project directory:

notebook-viewer --root ~/projects/my-analysis --notebook notebooks/report.ipynb --port 8770

Start without opening a browser:

notebook-viewer --root . --notebook analysis.ipynb --port 8770 --no-browser

Run a packaged live demo:

notebook-viewer --demo quickstart --port 8770
notebook-viewer --demo.signal_lab --port 8770

Stop a foreground server with Ctrl-C.

CLI

notebook-viewer [--root ROOT] [--notebook NOTEBOOK] [--demo DEMO] [--list-demos] [--host HOST] [--port PORT] [--no-browser]

Options:

  • --root: directory that readable notebooks must stay inside, default .
  • --notebook: notebook path relative to --root
  • --demo: copy and run a packaged demo notebook
  • --demo.NAME: shorthand for --demo NAME, for example --demo.motion_demo
  • --list-demos: list packaged demos and exit
  • --host: bind host, default 0.0.0.0
  • --port: bind port, default 8770
  • --no-browser: do not open a browser automatically

Packaged demos:

  • quickstart: markdown, stdout, a plot, a table, and collapsed code.
  • signal_lab: NumPy/SciPy signal synthesis, filtering, FFT, and spectrograms.
  • visual_story: generated images, color maps, and SVG output.
  • interactive_charts: pandas, seaborn, Plotly-style HTML, and sanitized rich output.
  • motion_demo: a small generated animation for lazy media loading.

How It Works

The viewer parses saved notebook JSON with the Python standard library and caches parsed notebooks by path, mtime, and size. Markdown headings define the outline. Selecting or scrolling to a section loads the cells for that section, while image and video outputs are represented as asset descriptors and streamed separately from /api/asset/<asset_id>.

Supported output behavior:

  • PNG, JPEG, GIF, SVG, and common video MIME outputs become lazy asset URLs.
  • HTML video data URLs are extracted into streamed video assets.
  • HTML tables and rich HTML outputs are sanitized before rendering.
  • stdout, stderr, tracebacks, and unsupported widgets use readable fallback blocks.
  • Code cells include raw source and highlighted HTML in the section API.

API

The local server exposes a small JSON/asset API:

  • GET /api/notebooks: list .ipynb files under --root
  • GET /api/notebook?path=...: return outline and section metadata
  • GET /api/section?path=...&section=...: return cells for one section
  • GET /api/asset/<asset_id>: stream decoded media assets
  • GET /api/demo-status?run_id=...: return live demo execution status

Notebook and section JSON responses avoid embedding large base64 media payloads.

Security Notes

ipynb-local-viewer is a local reader, not a notebook execution environment.

  • It never runs user-selected notebook code.
  • Demo mode only runs packaged demo notebooks and must be started explicitly.
  • It restricts notebook access to the configured --root.
  • It sanitizes markdown-rendered HTML and notebook HTML outputs.
  • It serves decoded media assets from .notebook_viewer_cache/.
  • Demo run copies are written under .notebook_viewer_cache/demo_runs/.

As with any local web server, bind it only where you intend to expose it. The default host is 0.0.0.0; use --host 127.0.0.1 for loopback-only access.

Development

Install development tools and run the test suite:

python -m pip install -e .
python -m pip install build twine trove-classifiers tomli
python -m unittest discover -s tests
python -m compileall src

Build and validate distribution artifacts:

python -m build
python -m twine check dist/*
python scripts/check_classifiers.py

Publishing

Releases are intended to use PyPI Trusted Publishing from GitHub Actions.

One-time PyPI setup:

  1. Log into the PyPI account masoudka.
  2. Create or select the PyPI project ipynb-local-viewer.
  3. Add a pending trusted publisher for:
    • Owner: msdkhairi
    • Repository: ipynb-viewer
    • Workflow: release.yml
    • Environment: pypi

Owner is the GitHub repository owner, not the PyPI username. The GitHub repository can remain ipynb-viewer even though the PyPI distribution name is ipynb-local-viewer.

Release flow:

git tag v0.1.0
git push origin v0.1.0

Then create a GitHub release for that tag. The release workflow builds the artifacts, validates them, and publishes with PyPI Trusted Publishing.

Manual fallback:

python -m build
python -m twine check dist/*
python -m twine upload dist/*

License

ipynb-local-viewer is distributed under the MIT License. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ipynb_local_viewer-0.1.1.tar.gz (41.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ipynb_local_viewer-0.1.1-py3-none-any.whl (42.5 kB view details)

Uploaded Python 3

File details

Details for the file ipynb_local_viewer-0.1.1.tar.gz.

File metadata

  • Download URL: ipynb_local_viewer-0.1.1.tar.gz
  • Upload date:
  • Size: 41.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ipynb_local_viewer-0.1.1.tar.gz
Algorithm Hash digest
SHA256 4c3bff16d3469e9e8bfbfd4ae9d8e75c599f5bf53f0b9f69b4aa17872c8d0dad
MD5 8150d6f6d81ced3567323a9bb7ed1ce2
BLAKE2b-256 f4184cfbf95abd23ce7b312e45a4cb95727cdc887b29f4660f86bd1d2f740832

See more details on using hashes here.

Provenance

The following attestation bundles were made for ipynb_local_viewer-0.1.1.tar.gz:

Publisher: release.yml on msdkhairi/ipynb-viewer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ipynb_local_viewer-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for ipynb_local_viewer-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2bad8223dff1f28a8ceb6d1d2146af328058a6916eae250c4127c2efb90a6b1b
MD5 fdb693920958664f32231a6bf449f1b8
BLAKE2b-256 54d4c65e7c82b4d271776f2186f6247d223319325e9cfc7c1f8ce4187a6959a2

See more details on using hashes here.

Provenance

The following attestation bundles were made for ipynb_local_viewer-0.1.1-py3-none-any.whl:

Publisher: release.yml on msdkhairi/ipynb-viewer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page