Skip to content

Feature: {nb-exec-table} directive — execution statistics table (myst-nb parity) #76

Description

@mmcky

Background

Every QuantEcon lecture series publishes an Execution Statistics page — a table of which notebooks were executed, how long each took, and whether it succeeded. It is our standing build-health signal: a reader (or maintainer) can open one page and see whether the whole book executed cleanly and how expensive each lecture is. See the live page for the Python Programming series: https://python-programming.quantecon.org/status.html

That page is generated by a single directive in status.md:

```{nb-exec-table}
```

Under Sphinx it is provided by myst-nb. Under mystmd it hard-errors, so the page renders as an error block with no table:

Diagnostic Where
⛔️ status.md:16 unknown directive: nb-exec-table every mystmd build of lecture-python-programming

This surfaced while validating QuantEcon/lecture-python-programming#363 (the jupyter-book 2 / mystmd migration branch) against main on this fork — v1.10.1 (qe-v8). It is the last hard error remaining from the original migration-warnings sweep in QuantEcon/lecture-python-programming#344; the index-syntax and figure scale warnings listed there have since been fixed.

What the Sphinx directive produces

myst-nb implements it in myst_nb/ext/execution_tables.py as one row per notebook in the project, with these columns:

Column Source
Document the notebook's docname
Modified source mtime
Method how it was run — cache hit, forced execution, etc.
Run Time (s) wall-clock execution time
Status succeeded / failed

Why it does not exist in mystmd

Upstream tracks it only as an unchecked line item in the broad feature-parity audit jupyter-book#189 ("Audit of Features missing in JupyterBook"), open since 2023 and listing it alongside bibliography, grid-item and grid-item-card. There is no dedicated upstream issue and no sign of movement, so if we want it for the migration it likely has to start here.

Implementation sketch

Most of the underlying data already exists — the gap is that it is logged rather than retained. During a build with --execute, myst-execute already knows per-notebook cache state and the CLI already prints per-file timing, e.g. 💿 Executing notebook (polars.md) [no execution cache found] followed by 📖 Built polars.md in 26 s. Execution results are persisted per notebook by packages/myst-execute/src/cache.ts (LocalDiskCache, hash-keyed JSON under _build/execute), but that cache stores outputs, not execution metadata.

So a plausible shape is:

  1. Have the execution pass record a small per-notebook stats record (path, mtime, method, runtime, success) into the session/store rather than only emitting it to the log.
  2. Add an nb-exec-table directive that reads those records at render time and emits a standard table node — so it inherits table styling from whichever theme is in use, including quantecon-theme.mystmd.
  3. Decide the no-execution case: when a build runs without --execute there are no stats, and the directive should degrade to a clear note rather than an error or an empty table.

Ordering is the main design question — the directive renders while other pages may still be executing, so the table either needs to be populated in a late pass or the page has to be built last.

Worth considering instead

This is a build diagnostic rather than lecture content, and it is the only thing keeping status.md from building clean. If implementing it in the fork is not judged worth the maintenance, the alternative is to retire the directive from the lecture sources and surface execution stats from CI instead — the same data is already in the build log and could be published as a job summary or artifact. Recording that here so the trade-off is explicit rather than defaulted into.

Links

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions