A local-first notebook system for Python, inspired by Clerk for Clojure
Project description
Plaque
A local-first notebook system for Python, inspired by Clerk for Clojure. Plaque turns regular Python files into interactive notebooks with real-time updates and smart dependency tracking.
👉 Check out examples/getting-started.py and its rendered version at examples/getting-started.html to see Plaque in action or watch the 🎥Demo Video
Features
- Local-first: Uses plain Python files as the source - and your own editor - no special file formats
- Live Updates: Browser preview updates in real-time as you edit
- Rich Output: Supports Markdown, LaTeX equations, plots, DataFrames, and more
- Flexible Format: Supports both
# %%markers and multiline comments for cells - Python-native: Use standard Python syntax for both code and documentation
- IPython Support: Magic commands (
%timeit,%%time, etc.) and top-level async/await - Download Button: Rendered notebooks include a download link to get the original Python source
Principles
Many systems support reactive notebooks, like clerk, marimo, observable, pluto, etc. Plaque is meant to be a simple thing that provides 80% of the utility with a very simple package. The core idea is that your files should only run as they would if you ran them from scratch from top to bottom, but we don't actually have to rerun every cell every time. Instead, we only ever re-execute any cell you modify and any cells later in the document.
In this way, you can have most of the benefits for reactivity and live updating, but still get caching and some gaurentee that you don't have to re-evaluate expensive computations.
Usage
Plaque supports two different styles for creating notebooks:
1. Traditional Cell Markers
Using # %% markers, similar to VS Code notebooks:
# Code cell
x = 42
print(f"The answer is {x}")
# %% [markdown]
# # This is a markdown cell
#
# With support for:
# - Lists
# - **Bold text**
# - And more!
# %%
# Another code cell
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [1, 4, 9])
plt.show()
2. Multiline Comments as Cells
Using Python's multiline strings (""" or ''') for documentation:
"""
# Getting Started
This notebook demonstrates using multiline comments as markdown cells.
All standard markdown features are supported:
1. **Bold text**
2. *Italic text*
3. Code blocks
4. LaTeX equations: $E = mc^2$
"""
# Code is automatically treated as a code cell
x = 42
print(f"The answer is {x}")
"""
## Data Visualization
Now let's make a plot:
"""
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [1, 4, 9])
plt.show()
"""
The plot shows a quadratic relationship between x and y.
"""
3. F-style Top Level Comments (Programmatic Templates)
Using f-string style comments for programmatic templated output:
f"""
# Dynamic Report for {dataset_name}
Results generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
## Summary Statistics
- Total samples: {len(data)}
- Mean value: {np.mean(data):.2f}
- Standard deviation: {np.std(data):.2f}
"""
dataset_name = "Sales Data Q4"
data = [1, 2, 3, 4, 5]
f"""
## Analysis Results
The dataset '{dataset_name}' contains {len(data)} data points.
Maximum value observed: {max(data)}
"""
F-style comments allow you to create dynamic markdown cells that incorporate variables and expressions, making them perfect for automated reports and templated notebooks.
Both styles support:
- Markdown formatting with bold, italic, lists, etc.
- LaTeX equations (both inline and display)
- Code syntax highlighting
- Rich output (plots, DataFrames, etc.)
IPython Features
Plaque uses IPython as its execution engine, which means you can use:
Magic Commands:
# Time a single line
%timeit sum(range(1000))
# Time an entire cell
%%time
result = expensive_computation()
# List variables in namespace
%who
# Get help on objects
my_function?
Top-level Async/Await:
import asyncio
async def fetch_data(url):
await asyncio.sleep(0.1)
return {"data": "result"}
# Use await directly at the top level - no asyncio.run() needed!
result = await fetch_data("https://api.example.com")
result
Shell Commands:
# Run shell commands with !
!ls -la
!pip list | grep numpy
Guidelines for Multiline Comments
When using multiline comments as cells:
- Top-level comments become markdown cells
- Function/method docstrings remain as code
- You can mix code and documentation freely
- Both
"""and'''are supported
Installation
You can install Plaque using either pip or uv:
Install from PyPI
# Using pip
pip install plaque
# Using uv (recommended)
uv pip install plaque
Local Development
# Clone the repository
git clone https://github.com/alexalemi/plaque.git
cd plaque
# Install in development mode
uv pip install -e .
# or
pip install -e .
Development Setup with Dependencies
For development work with testing and additional tools:
# Clone the repository
git clone https://github.com/alexalemi/plaque.git
cd plaque
# Create and activate a virtual environment (optional)
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install with development dependencies
uv pip install -e ".[dev]"
# or
pip install -e ".[dev]"
Running a Notebook
To render a notebook:
# Generate static HTML
plaque render my_notebook.py
# Generate static HTML with custom output path
plaque render my_notebook.py output.html
# Start a live re-render with caching.
plaque watch my_notebook.py
# Start live server with auto-reload
plaque serve my_notebook.py
# Specify a custom port (default is 5000)
plaque serve my_notebook.py --port 8000
# Open browser automatically
plaque serve my_notebook.py --open
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
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 plaque-0.4.0.tar.gz.
File metadata
- Download URL: plaque-0.4.0.tar.gz
- Upload date:
- Size: 157.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.2","id":"zara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0cfe948fb140f08d0f9259385017e79c88cbfa54b39884379ad28a4c8834ec74
|
|
| MD5 |
abadb8ed47cb7f8b1acabb8db4b504d5
|
|
| BLAKE2b-256 |
d94279fb8a1fb220c2148ce96faeeaa680b5b05d25195e8ea46d21369dfc1972
|
File details
Details for the file plaque-0.4.0-py3-none-any.whl.
File metadata
- Download URL: plaque-0.4.0-py3-none-any.whl
- Upload date:
- Size: 37.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.2","id":"zara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
452a1c69ea3b3021618db4b95655348d08c5166412ecad057f1d796419714291
|
|
| MD5 |
8fd90db1235b8b84ebede725672ad3ab
|
|
| BLAKE2b-256 |
d0ba1b5245e01d811589c76eeca3dd44e463a5b36ad1daf7dba56e4c8bb3a86a
|