Skip to content

feat: delegate ecModel YAML I/O to raven-python#19

Merged
edkerk merged 1 commit into
developfrom
feat/yaml-delegate-to-raven-python
May 30, 2026
Merged

feat: delegate ecModel YAML I/O to raven-python#19
edkerk merged 1 commit into
developfrom
feat/yaml-delegate-to-raven-python

Conversation

@edkerk
Copy link
Copy Markdown
Member

@edkerk edkerk commented May 30, 2026

Summary

save_ec_model and load_ec_model now delegate the cobra-side round-trip and the opaque preservation of GECKO top-level keys (ec-rxns, ec-enzymes, gecko_light, metaData) to raven_python.io.yaml. geckopy still owns the typed EcData interpretation, the legacy MATLAB ec-model normalisation, and the protein-direction flip for older models with reverse-sign usage_prot_* reactions.

What moved to raven-python

  • The cobra-shaped YAML round-trip (!!omap blocks for reactions/metabolites/genes/compartments).
  • The mechanism for stashing/preserving top-level non-cobra YAML keys via model.notes["_yaml_sections"] — so geckopy's GECKO blocks land at the document root, not nested inside notes.

Depends on raven-python PR #11 (merged).

What geckopy still owns

  • save_ec_model: builds ec-rxns / ec-enzymes / gecko_light from EcData (omitting empty source/notes/eccodes, kcat==0 → 'no kcat assigned', omitting NaN mw/concs and empty sequence), pre-coerces numpy/ruamel scalars via _to_native, stashes everything on model.notes within a try/finally so the caller's model is restored after the write, then delegates to raven_python.io.yaml.write_yaml_model.
  • load_ec_model: keeps its own _read_yaml (handles legacy bare-- sequence-of-single-key-maps), applies _normalize_legacy_layout (metaData lifting + smiles → annotation), hands the cleaned dict to raven-python's model_from_yaml_data, then reads ec-* blocks back from model.notes["_yaml_sections"] into a typed EcData.

Tests

Full test suite passes locally. Round-trip semantics covered by the existing test_save_load_ec_model.py and test_yaml_roundtrip.py suites.

Migration note

Users now need raven-python available; install via:

pip install "raven-python @ git+https://github.com/SysBioChalmers/raven-python.git@main"

(Already listed in pyproject.toml from the earlier delegation work.)

…p SBML

Mirrors MATLAB GECKO + RAVEN, where RAVEN's readYAMLmodel.m /
writeYAMLmodel.m populate and serialise the model.ec struct directly
and GECKO is just a consumer. The schema for ec-rxns / ec-enzymes /
gecko_light, the parsing, the legacy-format normalisations (top-level
smiles -> annotation, reverse-direction usage_prot_*, bare-`-`
document root) all live in raven-python now (see
raven_python.io.ec_data); geckopy keeps the algorithms that operate
on top.

geckopy.EcData is now a re-export of raven_python.io.EcData. Existing
`from geckopy import EcData` keeps working unchanged; the dataclass
gained EcData.empty (was empty_for_reactions) and kept .validate.

save_ec_model / load_ec_model become thin wrappers (~30 LOC each)
that add three application-level concerns on top of raven-python:

1. File-extension validation (YAML only; .xml/.sbml raises a helpful
   "SBML ecModel I/O has been removed" message).
2. Adapter-aware path resolution under <adapter.params.path>/models/.
3. Provenance + diagnostics: metaData injection on save (date, geckopy
   version, MATLAB-compat description); fast-fail messages on empty
   ec or non-ecModel YAML.

Removals:
- src/geckopy/io/sbml.py (437 LOC) — entire ecModel SBML I/O path.
  Per `cobra.io.read_sbml_model` is still used for loading conventional
  starting GEMs; only the ecModel-specific encode/decode is gone.
- src/geckopy/io/ (whole package) — only contained sbml.py.
- tests/test_sbml_io.py — covered the removed surface.
- tests/test_ec_data.py — EcData validation tests now live in
  raven-python's test_io_yaml_ec_data.py (covered by the upstream
  PR #12).
- The big libsbml-appendNotes-silently-fails gotcha in
  docs/future_improvements.md (no longer relevant; no libsbml use
  in geckopy proper). The Windows/Mac `e-005` -> `e-05 ` MATLAB SBML
  post-processing item likewise dropped.

Test renames:
- tests/test_ec_model.py: EcData.empty_for_reactions -> EcData.empty.

New tests:
- test_load_ec_model.test_sbml_extension_raises_with_helpful_message
- test_save_ec_model.test_sbml_extension_raises_with_helpful_message

Updated tests:
- test_load_ec_model.test_unknown_extension_raises: new "YAML only"
  message.
- test_load_ec_model.test_legacy_sequence_top_level_is_merged: now
  builds a complete bare-`-` doc from the canonical fixture and
  asserts the load succeeds (proving the merge in raven-python's
  reader is reached through the geckopy wrapper).
- test_save_ec_model.test_unknown_extension_raises: same message
  update.

Dependency:
- raven-python pin moved from @main to @develop. raven-python's main
  branch is currently just the initial commit; all active development
  lives on develop, including the typed model.ec / EcData feature
  this commit depends on. README and pyproject pins updated.

Docs updated:
- raven_integration.md: rewritten to describe the new clean split
  (raven-python owns YAML+schema, geckopy owns three application
  concerns).
- yaml_format.md: ec-* keys now listed as raven-python-owned.
- README: drop SBML mention, fix pin.

Full suite: 1254 passed, 1 pre-existing solver-state flake
unrelated to this change.

Depends on raven-python PR #12 (feat: typed model.ec via EcData)
landing on develop before geckopy install resolves the pin.
@edkerk edkerk force-pushed the feat/yaml-delegate-to-raven-python branch from 6b679a3 to 4e422a9 Compare May 30, 2026 19:34
@edkerk edkerk merged commit e6aed97 into develop May 30, 2026
@edkerk edkerk deleted the feat/yaml-delegate-to-raven-python branch May 30, 2026 19:43
@edkerk edkerk mentioned this pull request May 30, 2026
edkerk added a commit that referenced this pull request May 30, 2026
Roll-up commit for the second alpha. Bumps the version, adds the
CHANGELOG entry, ships the MIT LICENSE text the pyproject already
declared, drops the redundant requirements.txt, and tucks internal
planning notes under docs/internal/ so the user-facing docs/ tree
only carries reference documentation.

Highlights covered by [0.1.0a2] (see CHANGELOG.md for full notes):

- gecko-light ecModel end-to-end (PR #20).
- YAML I/O + typed EcData delegated to raven-python; SBML ecModel
  I/O removed (PR #19).
- ec_fseof re-aligned with raven_python.analysis.fseof (PR #21).
- get_conc_control_coeffs solver-state guard fix.
- raven-python pin moved from @main to @develop.

Repo housekeeping:

- LICENSE: MIT text added at repo root (the classifier and the
  pyproject license field already declared MIT, but no LICENSE file
  shipped previously — blocks GitHub repo metadata and any future
  PyPI publish).
- requirements.txt: deleted. It was a pip-freeze snapshot duplicating
  pyproject.toml's declared dependencies; pyproject is the source of
  truth.
- docs/internal/: brenda_refresh_plan, code_review,
  openkineticspredictor_plan, porting_plan, raven_inventory moved
  out of the user-facing docs/ tree. Two source-file docstrings
  updated to point at the new location.
- pyproject.toml: version 0.1.0a1 -> 0.1.0a2.

Release smoke:
- Full pytest suite green: 1259 passed, 1 skipped (network),
  1 deselected (smoke), 1 xfailed (documented).
- Light tutorial runs end-to-end against ecTestGEM.
- Both tutorial scripts compile cleanly. The full tutorial's
  end-to-end run is exercised piecewise by the unit suite; a live
  BRENDA + DLKcat + sensitivity-tuning replay was skipped for the
  release smoke (too long, no signal beyond the unit tests).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant