A lightweight IPython extension that records code cell execution history as Quarto Markdown (QMD).
Experiments are shaped by failed attempts as well as successful ones. Recording both preserves the trial-and-error process, giving an experiment notebook a coherent story instead of showing only its final results.
With pip:
pip install ipy-runlogIn a uv project:
uv add ipy-runlogLoad the extension — recording starts automatically:
%load_ext ipy_runlogThe log is written to .ipy_runlog/ in the current working directory. The
file name is generated from the current date and time, for example:
.ipy_runlog/20260611-123456.qmd
Recording stops automatically when the IPython session ends.
Check the current status:
%runlog statusSwitch to a new log file mid-session (closes the current log):
%runlog new "My Analysis Session" # title + derived filename: my-analysis-session.qmd
%runlog new "Feature Extraction" -d ./logs # custom output directoryUpdate configuration options in the current log's frontmatter (and rename the log file if title is updated) without interrupting recording:
%runlog set --title "My Analysis Session" --author "Jane Doe"Write a comment directly to the active QMD log file (to leave a text note between execution records):
%runlog comment "We started training the model here."Stop recording manually:
%runlog stopShow help:
%runlog help
%runlog new --helpYou can set defaults in pyproject.toml:
[tool.ipy-runlog]
directory = "./logs"
author = "Jane Doe"Or in .ipy_runlog.toml at the project root (used as a fallback when
pyproject.toml is absent or has no [tool.ipy-runlog] section):
directory = "./logs"
author = "Jane Doe"Available config keys:
| Key | Type | Default | Description |
|---|---|---|---|
directory |
string | .ipy_runlog/ |
Output directory |
author |
string | (none) | Author written into the QMD frontmatter |
The extension uses IPython event handlers to monitor cell execution:
pre_run_cell: Triggered before a cell is executed. The extension captures the source code of the cell at this point.post_run_cell: Triggered after a cell finishes executing. The extension calculates the elapsed time and determines if it was successful or failed (including error details).
Each cell is appended to the QMD file as an HTML comment with execution
metadata followed by a fenced Python code block. For cells that failed during execution, the #| error: true chunk option is included so that rendering with Quarto does not halt.
Logs are UTF-8 encoded Quarto Markdown files. Each file begins with a YAML frontmatter block:
---
title: "My Session"
author: "Jane Doe"
date: 2026-06-11T12:34:56.789012
---Each cell execution is recorded as:
<!-- cell: started=2026-06-11T12:35:00.000000, ended=2026-06-11T12:35:00.012000, status=success, elapsed=0.012s -->
```python
x = 1 + 1
```
<!-- cell: started=2026-06-11T12:36:00.000000, ended=2026-06-11T12:36:00.005000, status=failed, elapsed=0.005s -->
```python
#| error: true
print(undefined_variable)
```
Planned feature: Capturing cell output (stdout and rich display objects) is planned for a future release. The focus of the current version is on recording code and errors as a lightweight audit trail.
Install this repository in editable mode:
python -m pip install -e .With uv:
uv pip install -e .Run the test suite:
uv run pytest