Skip to main content

Write Python lecture code. Get an interactive viewer on GitHub Pages.

Project description

lectrace

Write Python lecture code. Get an interactive step-through viewer on GitHub Pages — automatically.

lectrace traces your Python code line by line using sys.settrace, captures variable state and rendered content at each step, and produces a static React app that lets anyone step through the execution with arrow keys. No Node.js, no configuration, no build step for the user — just Python.

Inspired by edtrace by Percy Liang.


Install

uv add lectrace
# or
pip install lectrace

Requires Python 3.11+. Zero mandatory dependencies — lectrace uses the standard library only. numpy, torch, and sympy are detected and rendered automatically if they are already installed in your environment.


A lecture file

A lecture is any .py file that imports from lectrace and defines a main() function:

# 01_binary_search.py
from lectrace import text, link

def binary_search(arr, target):
    lo, hi = 0, len(arr) - 1
    while lo <= hi:              # @inspect lo hi
        mid = (lo + hi) // 2    # @inspect mid
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1

def main():
    text("# Binary Search")
    text("Finds a target in a sorted array in $O(\\log n)$ time.")

    arr = [2, 5, 8, 12, 16, 23, 38, 42]  # @inspect arr
    result = binary_search(arr, 23)       # @inspect result

    text(f"Found 23 at index `{result}`")
    link(binary_search)   # click to jump to the function definition

Directives

Directives are inline comments that control tracing and display:

Directive Effect
# @inspect x y Show x and y in the variable panel after this line runs
# @clear x Remove x from the variable panel
# @stepover Execute this line as a single step — don't trace into any calls it makes
# @hide Run this line silently — never shown in the viewer

Rendering functions

Call these anywhere inside main() or any function it calls:

Function What it renders
text("# Heading") Markdown with LaTeX math ($...$ inline, $$...$$ display)
text("...", verbatim=True) Monospace, whitespace preserved
image("fig.png", width=400) Local file or remote URL (cached)
video("demo.mp4") Embedded video with controls
link(MyClass) Clickable jump to that class or function in the viewer
link(title="Paper", url="...", authors=["Smith"], date="2024") Reference card with hover metadata
plot({...}) Interactive Vega-Lite chart
note("speaker annotation") Presenter note, hidden until N is pressed
system_text(["python3", "--version"]) Shell command output as verbatim text

Custom type rendering

Implement __lectrace__ on any class to control how it appears in the variable panel:

class Node:
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

    def __lectrace__(self):
        return {
            "val": self.val,
            "left": self.left.val if self.left else None,
            "right": self.right.val if self.right else None,
        }

Without __lectrace__, nested objects show their full repr. With it, you control exactly what students see.


File naming

Pattern Behaviour
01_intro.py Lecture — appears in sidebar, traced and deployed
02_sorting.py Lecture — sidebar order follows alphabetical sort
_utils.py Helper — imported normally, never traced or shown

Number prefixes control sidebar order. Helper files starting with _ are ignored by lectrace entirely.

my-course/
  _data.py            ← shared data, ignored by lectrace
  01_intro.py         ← first in sidebar
  02_complexity.py    ← second
  03_sorting.py       ← third

CLI

lectrace serve                  # build + serve all lectures at http://localhost:7000
lectrace serve 01_intro.py      # serve a single file
lectrace build --output _site   # build static site for deployment
lectrace init                   # generate GitHub Actions workflow + lectrace.toml
lectrace run 01_intro.py        # execute and print trace stats (no server)

Deploy to GitHub Pages

lectrace init   # generates .github/workflows/lectrace.yml
git add .
git commit -m "add lectures"
git push

Enable GitHub Pages in your repo settings (Source: GitHub Actions). Every push to main rebuilds and redeploys automatically.


How it works

  • Tracersys.settrace intercepts every line of execution. At each step it captures the call stack, inspected variable values (serialized to JSON), and any pending renderings.
  • Serializer — converts Python values to JSON. Primitives are direct. Collections recurse. numpy/torch/sympy are imported lazily only when encountered.
  • Builder — discovers lecture files, runs each through the tracer, writes traces/*.json plus a traces/index.json manifest. Incremental: files are skipped if their SHA-256 hash hasn't changed.
  • Viewer — a pre-built React + TypeScript SPA bundled into lectrace/_static/ and shipped inside the pip package. Uses HashRouter so it works at any URL depth with zero configuration. Math via KaTeX, charts via Vega-Lite, syntax highlighting via highlight.js.

Documentation

Full documentation: https://praisegee.github.io/lectrace/

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

lectrace-1.0.0.tar.gz (1.5 MB view details)

Uploaded Source

Built Distribution

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

lectrace-1.0.0-py3-none-any.whl (1.4 MB view details)

Uploaded Python 3

File details

Details for the file lectrace-1.0.0.tar.gz.

File metadata

  • Download URL: lectrace-1.0.0.tar.gz
  • Upload date:
  • Size: 1.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for lectrace-1.0.0.tar.gz
Algorithm Hash digest
SHA256 b2105c47d07f22bcb413d22b2aa0c6887dabd9772eedc8fdaaa51ea7f04edd44
MD5 573a7f5c70388fd0918d8b69cdf87c61
BLAKE2b-256 7aca3e878e3cd62fd6c785daff7c959238860436d2867664ac1bc675537ed082

See more details on using hashes here.

File details

Details for the file lectrace-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: lectrace-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for lectrace-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ee59185be5386c874909915260cdbecc55d432a559961888bcbbcc8b80bf6723
MD5 8b4abc5bf4d25a81415bb68a076206ec
BLAKE2b-256 df0277cef38a713a73a305ff6e155fa698b325106cbd9266f7edac3f98e9ee56

See more details on using hashes here.

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