Plain .py files as notebooks
Project description
nobook
Plain .py files as notebooks. No .ipynb files ever.
Write Python with # @block=name markers. Each block becomes a Jupyter cell. The .py file is the notebook.
File format
# @block=setup
import math
x = 42
# @block=compute
result = math.sqrt(x)
print(f"sqrt({x}) = {result:.4f}")
A block starts at # @block=name and runs until the next # @block= or end of file. That's it.
Quick start
JupyterLab / Jupyter Notebook
# 1. Create a .py file with block markers
cat > demo.py << 'EOF'
# @block=hello
print("hello from nobook")
# @block=math
import math
print(f"pi = {math.pi:.4f}")
EOF
# 2. Launch Jupyter (no install needed)
uvx nobook
Jupyter opens. Right-click demo.py in the file browser and select Open as Nobook. It renders as a notebook with two cells (hello and math). Run them, edit them, save -- the file stays .py.
VS Code
Install the Nobook VS Code extension (coming soon).
Then:
- Open any
.pyfile with# @block=markers - Right-click and select "Open as Nobook"
- Or use the command palette: "Nobook: Create New Notebook"
As a project dependency
uv add nobook
uv run nobook
Opening .py files as notebooks
In JupyterLab / Jupyter Notebook, right-click any .py file and select Open as Nobook:
.py files containing # @block= markers will also auto-open as notebooks when double-clicked.
CLI commands
Launch Jupyter
uv run nobook # launches Jupyter Notebook (default)
uv run nobook lab # launches JupyterLab
uv run nobook jupyter # same as default, launches Jupyter Notebook
All launch commands accept extra arguments that are passed through to Jupyter:
uv run nobook --port=9999 --no-browser
uv run nobook lab --port=9999
Run blocks without Jupyter
uv run nobook run example.py # execute all blocks, write example.out.py
uv run nobook run example.py --block=setup # run up to and including "setup"
uv run nobook list example.py # print block names
Output goes to .out.py with results inlined as comments:
# @block=setup
import math
x = 42
# >>>
# @block=compute
result = math.sqrt(x)
print(f"sqrt({x}) = {result:.4f}")
# >>> sqrt(42) = 6.4807
Errors show as # !!! ... lines. Since output and errors are plain comments, .out.py files are valid Python -- you can run them directly with python example.out.py.
See examples/ for sample input and output files.
Manual launch (without the CLI wrapper)
uv run jupyter notebook --ServerApp.contents_manager_class=nobook.jupyter.contentsmanager.NobookContentsManager
Or for JupyterLab:
uv run jupyter lab --ServerApp.contents_manager_class=nobook.jupyter.contentsmanager.NobookContentsManager
How it works
Jupyter UI (standard, unmodified)
|
IPython Kernel (standard, unmodified)
|
NobookContentsManager <-- intercepts file I/O
|
.py files with # @block markers
The NobookContentsManager subclasses Jupyter's LargeFileManager. On get(), it parses # @block= markers and returns a notebook model (blocks as code cells). On save(), it converts the notebook model back to .py format. The kernel and UI are completely stock.
.py files without # @block= markers are served normally (as plain text files).
JupyterLab extension
Nobook includes a JupyterLab extension that adds:
- Launcher card -- click "Nobook" in the launcher to create a new
.pynotebook - "Open as Nobook" context menu -- right-click any
.pyfile to open it as a notebook - Block name labels -- editable labels on each cell showing the
@blockname
The extension is bundled with the package and installs automatically.
VS Code extension
The VS Code extension provides:
- Open
.pyfiles with# @block=markers as notebooks - Block name display on each cell
- "Open as Nobook" context menu
- "Create New Notebook" command
Install from VS Code Marketplace (coming soon).
Development
To test nobook from any project without installing it:
uv run --project <path-to-nobook> python -m nobook
Full development install
git clone <repo-url> && cd nobook
uv sync
make setup-all # Set up both JupyterLab and VS Code extensions
make build-all # Build both extensions
JupyterLab extension development
cd jupyterlab-ext
jlpm install
jlpm run watch
VS Code extension development
cd vscode-ext
npm install
npm run watch
# Press F5 in VS Code to launch Extension Development Host
Project structure
nobook/
├── nobook/ # Python package
├── jupyterlab-ext/ # JupyterLab extension (TypeScript)
├── vscode-ext/ # VS Code extension (TypeScript)
├── tests/ # Python tests
└── examples/ # Example notebooks
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nobook-0.0.3.tar.gz.
File metadata
- Download URL: nobook-0.0.3.tar.gz
- Upload date:
- Size: 220.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d12073b9a0c641a6b07bf63d241cb900bf4b0b15c7c44dd1ddaecd1bb2e0c8bf
|
|
| MD5 |
493d45514ad599663892119285473308
|
|
| BLAKE2b-256 |
56d90030e171ec23c589b44735c43dae651307189d25c460e39c44ade0e69d05
|
File details
Details for the file nobook-0.0.3-py3-none-any.whl.
File metadata
- Download URL: nobook-0.0.3-py3-none-any.whl
- Upload date:
- Size: 32.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed8105eefa43170ed2a6aa778e2f522a82c23d2620009b7bd868e624fea94965
|
|
| MD5 |
bbceb913543a8f17350c4be9a0f08e26
|
|
| BLAKE2b-256 |
50bc026ff8f4011090eb5ba43ba16cd6582edfbd79a0526422cf78b79a695e5a
|