Skip to main content

Silently log notebook cell executions and restore your debugging thread after an interruption gap.

Project description

recontext

Silently log every notebook cell you run, and — when you come back after stepping away — get a "here's where you were" banner before your next cell runs. No more reconstructing the debugging thread by hand after a 10-minute interruption.

recontext is pure IPython kernel hooks: no IDE extension, no frontend. It works identically in VSCode Jupyter, JupyterLab, and terminal IPython. The only runtime dependency is ipython>=8; everything else is the standard library. Zero network calls by default — all data stays on your machine.

─ recontext ───────────────────────────────────────────────────────────────────────────────────────────────
⏸ away 14m  (last activity 11:42:25)
GOAL: tracing weird nav_adj in pnl_attribution

AGO   SNIPPET                                          OUTPUT                       VARS             TOOK
14m   fig = px.line(mu_df, x='ts', y='mu')             fig → Figure                 fig             210ms
15m   mu_df, sig_df, _resid = fit_nb2(pnl, marks_df)                                mu_df, sig_df    6.2s
16m   marks = mkt.get_marks(syms)                      ✗ KeyError: 'RELIANCE'       marks            95ms
17m   pnl[pnl.nav_adj.abs() > 1e6]                     pnl[…] → DataFrame (3, 12)                   140ms
18m   pnl = attr.load('2026-06-08')                                                 pnl              3.1s
(1 _var hidden · %recontext_config hide_underscore=off to show)

%wtf for more · %wtf --full for full sources
─────────────────────────────────────────────────────────────────────────────────────────────────────────

Each row is one executed cell — one activity line, most recent at the top, since that's where your eye lands when you come back. Read it left to right: how long ago, what you ran, what came out, what it bound, how long it took. Errors are the red rows; OUTPUT names the displayed expression (pnl[…] → DataFrame (3, 12)), and DataFrames and plots collapse to one-line summaries like DataFrame (84211, 12) / Figure. VARS shows every variable the cell bound (wrapping onto extra lines when needed — nothing is summarized away); throwaway _-prefixed names (_, _resid, …) are kept out by default — when that happens the banner says so in a one-line note, and %recontext_config hide_underscore=off brings them back. In a color terminal each variable name gets its own stable color everywhere it appears, so you can trace one variable across the trail at a glance — timings render dim so the code stays the brightest thing on screen (NO_COLOR turns color off).

60-second quickstart

python -m build                       # -> dist/recontext-*.whl  (needs: pip install build)
pip install dist/recontext-*.whl        # install into the SAME env your kernel uses

Then, in any notebook or IPython session:

%load_ext recontext

which answers with the whole tutorial:

recontext: on — logging every cell you run, locally. Nothing leaves this machine.

Pulled away mid-trace? When you come back after 4m+, your next cell
opens with where you were — goal, recent cells, outputs, errors — so you
pick the trace back up instead of re-tracing it from the beginning.

  %wtf                         where you were, on demand — live in Jupyter
  %goal <what you're chasing>  leave the breadcrumb — every banner leads with it
  %recontext_config              knobs (gap, banner, live, …)

That's it. From here recontext logs silently in the background: you won't see anything else until you step away longer than the gap threshold (default 4 min) and run your next cell — then the resume banner appears above that cell's output.

Drive it on demand

%wtf                 # banner with the last 8 events (alias: %recontext)
%wtf -n 20           # last 20 events
%wtf --full          # untruncated sources + results
%wtf --last          # the trail from your PREVIOUS session (after a kernel restart)
%wtf --stats         # per-day usage counters, last 7 days
%wtf --ai            # optional 2–3 sentence LLM summary (opt-in, see below)

%goal tracing weird nav_adj in pnl_attribution   # leave yourself a breadcrumb
%goal                                            # print the current goal
%goal --clear                                    # clear it

%recontext_config                      # print the current config
%recontext_config gap_seconds=300      # widen the gap to 5 min (session-scoped)
%recontext_config banner=off           # silence the auto-banner (magics still work)
%recontext_config hide_underscore=off  # show _-prefixed names in VARS again
%recontext_config live=off             # freeze %wtf into plain static prints

In Jupyter frontends the %wtf table is live: run it once and it keeps itself current, repainting in place as each cell finishes and whenever the goal changes (the newest %wtf is the one that stays live). In terminal IPython — or with live=off — it's the same table as a static print.

The goal is shown at the top of every banner — so when you return you're reminded what you were chasing, not just what you ran.

Permanent autoload

To skip %load_ext in every session, add recontext to your IPython config. Edit (or create) ~/.ipython/profile_default/ipython_config.py:

c.InteractiveShellApp.extensions = ["recontext"]

Startup-file alternative — drop ~/.ipython/profile_default/startup/00-recontext.py:

get_ipython().run_line_magic("load_ext", "recontext")

Reload after re-installing with %reload_ext recontext; remove cleanly with %unload_ext recontext.

Configuration

Session config (set with %recontext_config k=v, reset on kernel restart):

knob default what it does
gap_seconds 240 seconds away before the resume banner fires
trail_len 8 how many events %wtf shows by default
banner on off silences the auto-banner (magics still work)
hide_underscore on hide _-prefixed names from VARS (a note says when it did); off shows them
live on %wtf repaints in place as you work (Jupyter frontends); off = static prints, and disarms the current live view

Environment overrides, read at load time — precedence is env → %recontext_config → default:

env var overrides example
RECONTEXT_GAP_SECONDS gap_seconds export RECONTEXT_GAP_SECONDS=300
RECONTEXT_DIR data directory export RECONTEXT_DIR=~/work/.recontext
RECONTEXT_BANNER banner (0/off to silence) export RECONTEXT_BANNER=0
RECONTEXT_HIDE_UNDERSCORE hide_underscore (0/off to show _ names) export RECONTEXT_HIDE_UNDERSCORE=0
RECONTEXT_LIVE live (0/off for static prints) export RECONTEXT_LIVE=0
RECONTEXT_MODEL model used by %wtf --ai export RECONTEXT_MODEL=claude-sonnet-4-6

ANSI color is on by default (notebooks render it even though they aren't a TTY) and is suppressed entirely when NO_COLOR is set.

All data stays on your machine

recontext makes zero network calls by default. Everything it writes lives under ~/.recontext/ (override with RECONTEXT_DIR), and every file is created at mode 0600 (owner read/write only):

path what
sessions/YYYY-MM-DD_<id>.jsonl one file per kernel session — the event + goal trail, created lazily on your first cell
stats.json local per-day usage counters (events, resumes_shown, wtf_calls, goals_set)
errors.log the silent-failure sink: if a hook ever hits an internal error it logs here and stays quiet, never raising into your cell

If a banner or magic "does nothing", read ~/.recontext/errors.log first.

There is no telemetry, no analytics, and no auto-update.

The one optional network feature: %wtf --ai

%wtf --ai is the only feature that touches the network, and only when you explicitly invoke it and have ANTHROPIC_API_KEY set:

export ANTHROPIC_API_KEY=sk-ant-...

It POSTs your recent cell sources (truncated) to the Anthropic Messages API over stdlib urllib with a 10 s timeout and prints a 2–3 sentence summary. The first time you use it per session it warns you that cell sources leave your machine — check your compliance policy. If the key is missing it just tells you how to set it; any failure degrades to one line, never a traceback.

Develop

python -m pytest                # full suite (test_core, test_render, test_store)
ruff check src/ tests/          # lint
ruff format src/ tests/         # format
mypy src/recontext                # optional type-check, kept green

The per-cell overhead budget (< 5 ms mean over 1000 cells) is asserted inside tests/test_core.py, so python -m pytest is all you run to check it.

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

recontext-0.1.0.tar.gz (35.3 kB view details)

Uploaded Source

Built Distribution

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

recontext-0.1.0-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

Details for the file recontext-0.1.0.tar.gz.

File metadata

  • Download URL: recontext-0.1.0.tar.gz
  • Upload date:
  • Size: 35.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for recontext-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1cc78ca181739bc9a19c79bd05d31ca96d77a94b3eb9dc3c8c008663b6042ebe
MD5 063aab08d54f233882764ef125d64063
BLAKE2b-256 718286d6dd058915ffe76e831b62f3429c8dbf485a96fcaad97ce4f21e4dedad

See more details on using hashes here.

File details

Details for the file recontext-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: recontext-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for recontext-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1f3c09a4d7b1e2cfa21c4a70e7047f6f24c3bec15ed2b61b74036fcc3bb7753b
MD5 63b29372e5999ffa13f2d49677d7a49b
BLAKE2b-256 8e5b7d9de14d17aa1f1e996ac250a7ae56f663367663b6e7cb94bdfaa073b809

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