Skip to content

Adding a teaching pathway (integration template)

Use this guide whenever you add a new pathway graph, extend an existing module with another named graph, or add a shared mechanism used by edges.

Rule: code graph first → export mermaid → tests prove integration.
Never hand-edit auto pathway.mermaid and never leave a graph off the registry.

Reference implementations:

Example Why it is a good model
ketolysis.py + tests/test_ketolysis.py Single pathway, references, clinical teaching point
amino_acid_catabolism.py Multi-graph module, mechanism_id links, extra_summary
packs/COVERAGE.md Honest map of graphs vs gaps

Copy-paste assets:


What counts as a pathway vs not

Add a pathway pack Do not add a pack folder
Node/edge process graph (glycolysis, BCAA, dig) registry.py, __init__.py
Nutrient-sensing networks with edges metabolic_mechanisms.py (catalog only)
Classification map that is still a graph pathway_regulation.py (activity 0–1 rules)

Product meal score / vendor-variable formulas stay out of this repo (patent pending).

Shadowing trap: never create a directory with the same name as a .py module (e.g. beta_oxidation/ next to beta_oxidation.py). Mermaids live under pathways/packs/<id>/.


Integration checklist (do in order)

1. Code — graph in Python

  • [ ] Prefer extending an existing themed module when it fits (e.g. another AA map → amino_acid_catabolism.py).
  • [ ] New domain → new module src/biology_as_code/pathways/<theme>.py (copy pathway_module_stub.py).
  • [ ] Pathway name is stable, snake_case, unique across the registry.
  • [ ] nodes + edges non-empty; every edge from_node / to_node exists.
  • [ ] Teaching description + optional references (real sources only — no invented citations).
  • [ ] Optional: mechanism_id on key edges; register new mechanisms first (step 2).
  • [ ] Optional: extra_summary / summary() fields for invariants tests assert on.
  • [ ] Registry class with register / get / list_all (or at least .pathways dict).
  • [ ] Factory: get_<theme>_registry().
  • [ ] Add MetabolicMechanism(...) in src/biology_as_code/pathways/metabolic_mechanisms.py.
  • [ ] Stable id (snake_case); set related_pathways to your pathway name(s).
  • [ ] Cofactors / location / regulation when teaching-relevant.

3. Discovery — single wire point

  • [ ] Import factory + append to pathway_loaders() in src/biology_as_code/pathways/registry.py.
  • [ ] Only place to register loaders. Export and public API both use this list.
# registry.py — pathway_loaders() return list
("my_theme", get_my_theme_registry),
  • [ ] Confirm discoverability:
cd biology_as_code
PYTHONPATH=src python3 -c "
from biology_as_code import list_pathways, get_pathway
assert 'my_pathway' in [n.lower() for n in list_pathways()]
p = get_pathway('my_pathway')
print(p.name, len(p.nodes), len(p.edges))
"

4. Mermaid packs (auto — do not hand-write topology)

PYTHONPATH=src python3 scripts/export_pathway_packs.py

Creates / refreshes:

src/biology_as_code/pathways/packs/<pathway_name>/
  pathway.mermaid   # auto from live graph
  tests.md          # structural notes + checklist
  README.md
  • [ ] pathway.mermaid contains flowchart and at least one edge (-->).
  • [ ] Optional gold extras only under packs/<id>/<id>_extra/ (see glycolysis).
  • [ ] Never edit auto mermaid by hand — re-export after graph changes.

5. Coverage + docs

  • [ ] Update src/biology_as_code/pathways/packs/COVERAGE.md (row for the graph + textbook-gap honesty if relevant).
  • [ ] INDEX.md is regenerated by export — do not hand-maintain counts.
  • [ ] If the pathway is user-facing in README “what's inside”, add a short mention (optional; not required for every supporting graph).
  • [ ] Change log entry if this is a release-facing feature (CHANGELOG.md).
  • [ ] No fabricated sources. Prefer textbook + PMC/DOI/LibreTexts style refs like ketolysis.

6. Tests

Minimum bar:

  • [ ] Discoverable via list_pathways / get_pathway.
  • [ ] Structural: nodes ≥ 1, edges ≥ 1, endpoints resolve.
  • [ ] 1–3 biochemical invariants (enzyme markers, products, clinical hook).
  • [ ] If mechanism_id set → id exists in mechanism registry.

Patterns:

  • Full module: tests/test_ketolysis.py, tests/test_amino_acid_catabolism.py
  • Shared pack suite: tests/test_pathway_packs.py (always re-run after export)
PYTHONPATH=src python3 tests/test_pathway_packs.py
PYTHONPATH=src python3 -m pytest tests/test_my_pathway.py -q   # if pytest installed
# or import-and-call tests without pytest (see test_ketolysis style)

7. Integration gate (required before PR)

cd biology_as_code
PYTHONPATH=src python3 scripts/check_pathway_integration.py
# focus one new graph:
PYTHONPATH=src python3 scripts/check_pathway_integration.py --pathway my_pathway

Must exit 0. This checks discovery ↔ packs parity, mermaid validity, edge endpoints, mechanism resolution, and COVERAGE mentions.

8. Optional: regulation / dig / public API

Only if the feature needs it:

Hook When
pathway_regulation.py Fed/fast activity 0–1 for this pathway name
Dig residual / machines GI process, not a metabolic teaching graph
biology_as_code/__init__.py New public symbol (rare — prefer registry discovery)
Cookbook / VALIDATION docs Evidence-backed claim or law, not every graph

9. PR hygiene

  • [ ] Paste filled NEW_PATHWAY_CHECKLIST.md into the PR body.
  • [ ] ruff check on touched files; keep zero runtime deps.
  • [ ] No product-score / proprietary paths.
  • [ ] Empty beats fake — missing stoichiometry stays “teaching / TBD”, not invented numbers.

Commands cheat sheet

cd biology_as_code
pip install -e ".[dev]"          # once

# after editing graphs
PYTHONPATH=src python3 scripts/export_pathway_packs.py
PYTHONPATH=src python3 scripts/check_pathway_integration.py
PYTHONPATH=src python3 tests/test_pathway_packs.py

# full contributor bar
ruff check src tests --exclude tests/_legacy_test_pathways_source.py
pytest -q                        # if available

Decision tree (quick)

Is this a node/edge teaching process?
  NO  → mechanism catalog, regulation rules, dig machine, or data PR
        (different guide — see CONTRIBUTING.md / contributing-data.md)
  YES → Does an existing themed module fit?
          YES → add graph + _build_* there
          NO  → new module from stub
        → wire registry.pathway_loaders only
        → export packs
        → COVERAGE + tests
        → check_pathway_integration.py

Anti-patterns

Don't Do instead
Hand-draw mermaid without a Python graph Build graph, then export
Add pack folder only Registry first
Duplicate loaders in export_pathway_packs.py Wire registry.py only
Name pack dir same as .py module at pathways root Use packs/<id>/
Invent PMIDs / magnitudes OPEN / omit / cite real sources
Twenty empty one-AA files High-value maps + classification (see AA module)
Put meal-score weights in open package Out of scope