Release notes for sbmlutils 0.17.0
We are pleased to release the next version of sbmlutils including the following changes. The emSign root CA, whose intermediate keys were compromised, is no longer trusted: sbmlutils requires certifi>=2026.10.19 (GHSA-6q48-6c7w-9gw2) and is built and tested with uv 0.13.4 (GHSA-hq85-5cpj-mr62). Model creation reports construction and preservation diagnostics and can reject lossy input with strict=True and strict_preservation=True, large models are read faster and untrusted input can be limited (#509, #505). The release has breaking changes: spreadsheet annotations are applied before the final file is written, Antimony conversions release their models and serialize access to the native registry, and merge and BioModels identifiers as well as output paths are checked, see Breaking changes below (#509).
Security
certifi>=2026.10.19is a dependency: sbmlutils reaches the network through requests, which verifies with the CA bundle of certifi, and certifi 2026.10.19 removes the distrusted emSign root (GHSA-6q48-6c7w-9gw2) (#510)- continuous integration, the documentation and the release are built with uv 0.13.4, whose bundled CA store removes the emSign root (GHSA-hq85-5cpj-mr62) (#510)
New features
- model creation returns immutable, grouped construction diagnostics separately from the final validation; the opt-in
strict=Truerejects reported input losses, failed checked libSBML operations and undeclared targets of rules and initial assignments before writing, preserving an existing output file; the default continues to create missing target parameters;ConstructionErrorexposes the findings, annotation resources retained verbatim are informational (#509) - the SBML parser reports grouped known round-trip losses through
Model.preservation_diagnostics; factory results carry them independently from the construction and validation findings, also after merging models; the opt-instrict_preservation=Trueof parsing or model creation raisesPreservationError, and a strict write rejects known source losses before touching its destination; default parsing and writing remain permissive (#509) FactoryResult.validationexposes the validation result of the final file, after annotations;create_model(raise_on_error=True)raises on validation errors while leaving the file available for diagnosis (#509)ValidationOptions.fast()keeps structural checks and skips unit analysis (#509)- reports can skip derived units, XML and LaTeX with
include_derived_units,include_xmlandinclude_math;write_jsonwrites to a path or text stream without allocating the complete JSON string (#509) - reading and validation accept optional
max_byteslimits on decompressed input andallow_external_models=Falseto reject external comp references before validation (#509)
Breaking changes
- model creation applies spreadsheet annotations before writing and validating the final file; an annotation failure no longer leaves an intermediate, unannotated output file (#509)
- Antimony conversions release their loaded models after each call and serialize access to the native registry; applications using Antimony directly must coordinate that access or use separate processes (#509)
- merge identifiers must be valid SBML IDs, and BioModels identifiers must contain only ASCII letters, digits,
_or-; output paths which resolve outside their directory are rejected (#509)
Fixes
- report JSON preserves zero values and false flags, including a neutral FBC species charge; initial assignments without math no longer crash report generation (#509)
- primary keys of unnamed report elements use a traversal-local list index, avoiding quadratic scans (#509)
- Level 3 parameter units are resolved from their declarations without whole-model unit analysis, with a cache scoped to each model and traversal (#509)
- namespace-prefixed and malformed XML strings are recognized as content, and documented string filenames no longer log an error (#509)
ValidationOptions(modeling_practice=False)disables the modeling-practice checks (#509)- ordinary IO, factory and parser imports no longer load Antimony or the ODE exporter until a conversion requests them (#509)
- all elements of a model are walked in linear time (
utils.all_elements), libsbml'sget(i)walked the list from its head every time: reading Recon3D withsbml_to_modeltakes 0.2 s instead of 13 s in that walk; the parser, the validator, the copasi converter and the data driving use it (#505) - the context managers are annotated as
Generator, as ty 0.0.85 requires (#504)
Packaging and development
- continuous integration runs python 3.14 on linux, macos and windows and python 3.12 with the minimum direct dependencies; the other python versions and
cobraare tested locally withtox run-parallel, every workflow cancels a superseded run, uv caches the interpreters along with the packages, pytest runs on every core and lists the 15 slowest tests, theslowtests run locally only, dependabot proposes its updates monthly (#505, #509) - a fresh-process performance report measures imports, validation, reports and native peak memory (#509)
- the design documents and plans of coding agents are removed from the repository and gitignored (#505)
- dependency updates: sbmlode 0.3.0, ruff 0.16.10, ty 0.0.85, tox 4.64.9, zensical 0.0.68 in the lock, the pre-commit hooks of ruff and ty,
actions/upload-artifact7.0.2 andactions/download-artifact8.0.2 (#502, #503, #506, #507, #508) - the release notes of #509 moved from the notes of the released 0.16.0 into these notes of 0.17.0;
release-notes/0.16.0.mdis again the text of the 0.16.0 release
