Skip to content

Commit b20a89e

Browse files
committed
feat(io.yaml): factor model_from_yaml_data out of read_yaml_model
read_yaml_model now opens+parses the file then delegates the post-parse work (capturing per-entry side-fields onto notes, restoring legacy metaData id/name, stashing unknown top-level sections onto model.notes['_yaml_sections']) to a new model_from_yaml_data(raw: dict) helper. This lets downstream packages that need to pre-normalise their YAML before cobra reads it (e.g. geckopy, which lifts legacy MATLAB ec-model quirks like top-level per-metabolite `smiles` into `annotation` and merges bare-`-` sequence-of-single-key-maps back to a mapping) hand the cleaned dict directly to the post-parse pipeline, without round-tripping through a temp file. Both functions are exported from raven_python.io.yaml. Pure refactor on the read side; no behaviour change for existing read_yaml_model callers.
1 parent 0f3ec0d commit b20a89e

1 file changed

Lines changed: 21 additions & 1 deletion

File tree

src/raven_python/io/yaml.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,33 @@ def _capture_entry_fields(entries, fields):
8686

8787

8888
def read_yaml_model(path: str | Path) -> cobra.Model:
89-
"""Read a RAVEN/cobrapy YAML model into a ``cobra.Model``."""
89+
"""Read a RAVEN/cobrapy YAML model into a ``cobra.Model``.
90+
91+
Convenience wrapper around :func:`model_from_yaml_data` that opens the
92+
file (transparently un-gzipping ``.gz``) and parses the YAML. Callers
93+
that need to pre-process the document (e.g. lift legacy fields that
94+
cobra doesn't recognise) can read+normalise themselves and call
95+
:func:`model_from_yaml_data` with the resulting dict.
96+
"""
9097
with _open_text(path, "r") as handle:
9198
raw = _to_plain(_cobra_yaml.load(handle))
9299

93100
if not isinstance(raw, dict):
94101
raise ValueError(f"{path}: top-level YAML is a {type(raw).__name__}, not a mapping.")
102+
return model_from_yaml_data(raw)
103+
95104

105+
def model_from_yaml_data(raw: dict) -> cobra.Model:
106+
"""Build a ``cobra.Model`` from an already-parsed RAVEN/cobrapy YAML dict.
107+
108+
Strips and restores the RAVEN per-entry side-fields onto each entry's
109+
``.notes``, lifts ``id``/``name`` out of legacy ``metaData``, and
110+
stashes everything else (``version``, the ``metaData`` block itself,
111+
and any unknown top-level keys such as ``ec-rxns``/``ec-enzymes``)
112+
onto ``model.notes`` so a round-trip via :func:`write_yaml_model`
113+
preserves them. ``raw`` is mutated in place — copy it first if the
114+
caller needs the original.
115+
"""
96116
metadata = raw.pop("metaData", None) or {}
97117
version = raw.pop("version", None)
98118
foreign = {k: raw.pop(k) for k in list(raw) if k not in _COBRA_TOP_KEYS}

0 commit comments

Comments
 (0)