Skip to content

feat: Colab maturity — generated setup cells, setup_colab registry, URL guards #124

Description

@Jammy2211

Overview

A census of the Google Colab infrastructure (2026-07-09) found that while the release-time machinery is solid (tag bumper wired into release.yml, central Heart URL sweep), only 9 of 489 notebooks are actually Colab-runnable — docs and READMEs link 100+ notebooks (all HowTo chapters, the PyAutoFit flagship badge) that die on ModuleNotFoundError. This task makes Colab support mature and maintainable by construction: a generalized setup_colab registry in PyAutoConf, generation-time injection of a standard setup cell into every notebook in PyAutoBuild, and hardened forbidden-URL guards in PyAutoHeart. After this merges, the next release regenerates all notebooks Colab-ready automatically, with zero per-script maintenance.

Phase 2 (link rot: HowTo chapter README URLs, library-docs dead links, allowlist purges) is parked at PyAutoMind/feature/workspaces/colab_link_rot.md and will be issued when this phase nears shipping.

Plan

  • Generalize autoconf.setup_colab into one parameterized per-project registry covering all 6 notebook repos (autofit/autogalaxy/autolens workspaces + HowToFit/HowToGalaxy/HowToLens), fixing the GPU-detection bug, the import-time env mutation, and duplicated package lists; clone the release-matched tag shallowly; add the module's first unit tests.
  • Inject a standard Colab setup cell (markdown + code) into every notebook PyAutoBuild generates, parameterized by project, skipping notebooks that already carry a hand-written setup; add tests and document the end-to-end Colab architecture in docs/internals.md.
  • Extend PyAutoHeart's offline URL guard with the two rot classes the census found: unpinned blob/main Colab URLs (invisible to the release bumper) and Colab links to notebooks/chapter_* paths in workspace repos (chapters live in the HowTo repos). This intentionally turns the Monday sweep red until phase 2 fixes the rot.
Detailed implementation plan

Affected Repositories

  • PyAutoBuild (primary)
  • PyAutoConf
  • PyAutoHeart

Branch Survey

Repository Current Branch Dirty?
./PyAutoConf main clean
./PyAutoBuild main clean
./PyAutoHeart main clean

Suggested branch: feature/colab-maturity
Work Classification: Library
Worktree root: ~/Code/PyAutoLabs-wt/colab-maturity/ (created by /start_library)

Implementation Steps

  1. PyAutoConf — autoconf/setup_colab.py rewrite

    • _PROJECTS registry keyed autofit | autogalaxy | autolens | howtofit | howtogalaxy | howtolens → package list, workspace repo URL, workspace dir, display name, GPU error message. One shared extras list (pyvis, dill, jaxnnls, nautilus-sampler, timeout_decorator, anesthetic) + per-project core stack — kills the duplicated lists in for_autolens/for_autogalaxy.
    • Public API: setup(project: str, raise_error_if_not_gpu: bool = False). Keep for_autolens / for_autogalaxy as thin back-compat wrappers (released notebooks at old tags call them); add for_autofit and HowTo wrappers.
    • Fix check_jax_using_gpu: accumulate across all devices (today the last device wins) and handle the empty-device case (today UnboundLocalError).
    • Delete the module-level os.environ['XLA_FLAGS'] mutation (line 4) — it already happens inside _colab_setup; today every from autoconf import setup_colab clobbers user env even outside Colab.
    • Clone --depth 1 --branch <installed-version> (version via importlib.metadata.version of the project's top package), falling back to the default branch — removes the version skew between the pip-installed release, the tagged notebook, and today's main-HEAD clone; --depth 1 makes the clone fast on the large workspaces.
    • New test_autoconf/test_setup_colab.py: registry completeness/shape, wrapper delegation, clone tag-fallback (mocked subprocess), GPU-detection logic on stub device objects (numpy-only — no JAX in library unit tests), no import-time env mutation.
  2. PyAutoBuild — generation-time injection

    • autobuild/build_util.py: new inject_colab_setup(notebook_path, project) — prepend a markdown cell (what the cell does, GPU-runtime tip) and a code cell (try: import google.colab → bootstrap pip install autoconf --no-depsfrom autoconf import setup_colab; setup_colab.setup("<project>")). Skip injection when the notebook source already contains setup_colab (the 9 hand-written start_here setups keep working, no double setup).
    • autobuild/generate.py: call the injector after both py_to_notebook sites (root start_here*.py + the scripts loop), mapping the project CLI arg to the registry key. Copy-files (verbatim .py) are not notebooks and are not injected.
    • Tests (tests/): cell injected with valid JSON, idempotent, skip-if-present, project key threaded correctly.
    • docs/internals.md: new "Colab architecture" section — bootstrap module (PyAutoConf) → generation-time injection (Build) → release-time URL bumper (bump_colab_urls.sh) → weekly central sweep (Heart).
  3. PyAutoHeart — guard hardening

    • heart/checks/url_check.sh: two new forbidden entries: colab.research.google.com/github/PyAutoLabs/(autofit_workspace|autogalaxy_workspace|autolens_workspace|HowToFit|HowToGalaxy|HowToLens)/blob/main/ ("pin to a date tag — the release bumper skips main") and colab.research.google.com/github/PyAutoLabs/(autofit|autogalaxy|autolens)_workspace/blob/<ref>/notebooks/chapter_ ("chapter tutorials live in the HowTo repos").
    • Extend tests/test_url_check.py with both patterns (positive + negative cases).

Key Files

  • PyAutoConf/autoconf/setup_colab.py — runtime bootstrap, rewritten around the registry
  • PyAutoConf/test_autoconf/test_setup_colab.py — new test module
  • PyAutoBuild/autobuild/build_util.pypy_to_notebook + new inject_colab_setup
  • PyAutoBuild/autobuild/generate.py — injection call sites
  • PyAutoBuild/docs/internals.md — Colab architecture docs
  • PyAutoHeart/heart/checks/url_check.sh — forbidden-pattern guard
  • PyAutoHeart/tests/test_url_check.py — guard tests

Trade-offs

  • Setup cells go into all notebooks, including advanced pipelines impractical on Colab — harmless (no-op outside Colab, and bootstrap is still correct if opened there).
  • The --no-deps install strategy is deliberately kept (Colab ships the scientific stack; full dependency resolution is slow and can break Colab's numpy).
  • Injected cells use raise_error_if_not_gpu=False for frictionless first contact; the markdown cell tells users how to enable a GPU runtime.
  • The new Heart guard patterns will fail the Monday sweep until phase 2 lands — accepted forcing function.

Original Prompt

Click to expand starting prompt

See PyAutoMind/issued/colab_maturity.md — includes the full 2026-07-09 census (coverage counts, URL-form inventory, allowlist rot, setup_colab defect list).

We have most of the infrastructure in place to make workspace exampels and tutorials run in Google colab, such that users can mess around with everything without installation. This includes docs pointing to them, links on our README.md, etc. But, the infrastructure could be developed in a more mature and robust way, including better on going maintenance during release and whatnot. Given we only have Fable access until Sunday, can you do a census of the Google Colab setup for all projects and do the work to make it more polished, mature and maintainable?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions