Skip to content

0.10.0

Latest

Choose a tag to compare

@github-actions github-actions released this 07 Sep 15:34
· 6 commits to develop since this release

Release notes for sbmlutils 0.10.0

sbmlutils

We are pleased to release the next version of sbmlutils including the following changes. This is a large release which reorganizes the repository, so it starts with what has to be changed in existing code.

Breaking changes

  • sbml4humans moved into its own repository (#436), matthiaskoenig/sbml4humans, with its history. The Vue frontend, the deployment (Dockerfile, docker-compose-*.yml, nginx/, deploy.sh, deploy.md, docker-purge.sh) and the FastAPI backend went there: sbmlutils.report.api and sbmlutils.report.api_examples are gone and the fastapi, uvicorn and python-multipart dependencies with them, sbmlutils no longer ships a web service. The report itself stays here, i.e., report.sbmlinfo, report.units and report.mathml, and it is what the api serves; report.sbmlreport.create_online_report, the client which opens a model on sbml4humans.de, stays as well

  • pymetadata >= 0.6.0 is required, which reorganized its packages. Code which imports from pymetadata through sbmlutils is unaffected, code which imports from pymetadata directly changes from pymetadata.identifiers.miriam import BQB to from pymetadata.core.miriam import BQB and from pymetadata.metadata import SBO to from pymetadata.ontologies import SBO

  • sbmlutils.metadata.sbo removed, it only re-exported SBO: from sbmlutils.metadata.sbo import SBO becomes from sbmlutils.metadata import SBO. sbmlutils.metadata re-exports BQB, BQM and SBO explicitly instead of through star imports, the qualifier maps of libsbml stay in sbmlutils.metadata.miriam

  • SBO is a class of ontology terms now instead of a str enum. A term is still its identifier, i.e., SBO.SIMPLE_CHEMICAL == "SBO_0000247", and it carries label, definition, synonyms, curie and url

  • the examples moved out of the package to examples/ in the repository, so from sbmlutils.examples import ... and python -m sbmlutils.examples.<name> become from examples import ... and python -m examples.<name>, run from the root of a checkout. They are documentation and are no longer installed with the package, which shipped megabytes of models

  • log.get_logger() removed. sbmlutils configured logging on import: every module attached a rich handler to its logger and set its level, so an application had no say over the messages of the library. Code which called it changes from log.get_logger(__name__) to logging.getLogger(__name__); log.enable_rich_logging() is the opt-in for scripts, examples and interactive work. log.set_level_for_all_loggers() is gone as well, it set the level on every logger of the interpreter, including those of other libraries. Importing sbmlutils.console no longer replaces the interpreter displayhook through rich.pretty.install()

  • utils.timeit and utils.deprecated removed. Nothing used them and deprecated read f.func_code, a python 2 attribute, so it raised as soon as it was applied

  • comp.create_ports returns list[libsbml.Port], which is what it always returned; the annotation said list[factory.Port]. comp.replace_element_in_submodels returns None, it never returned the ReplacedElement its annotation promised

  • the coefficient of a UserDefinedConstraintComponent is the id of a parameter, not a number, as fbc version 3 defines it. A constraint is written as components={"RGLX": "coef_plus_one"} with the coefficients declared as parameters; passing numbers raised a TypeError from libsbml

  • unused dependencies dropped: depinfo, scipy, xmlschema and setuptools, which worked around a pkg_resources import of py4cytoscape that no longer exists

  • the installation is less than half the size (#461), 521 MB before, 201 MB now. The package reads, writes, annotates and validates models; it neither simulates nor plots, and libroadrunner (137 MB) and matplotlib were runtime dependencies although nothing in the package imports them. They are the examples extra now, py4cytoscape is the cytoscape extra and cobrapy the cobra extra, which the documentation promised but which was never declared:

    pip install sbmlutils[cytoscape]  # visualization in a running Cytoscape
    pip install sbmlutils[cobra]      # flux balance analysis with cobrapy
    pip install sbmlutils[examples]   # simulation and plotting, to run the examples

    sbmlutils.cytoscape still imports without its extra; its functions log a warning and do nothing, exactly as they already did when Cytoscape was not running. uv sync --extra dev installs cytoscape and examples, so a development environment is unchanged

  • the SBML test suite (56 MB) and the biomodels archives (21 MB) under sbmlutils/resources/models/ are excluded from the distribution, see [tool.hatch.build] in pyproject.toml. They are test data of the repository, not resources of the package; tests/test_parser.py resolves them from the checkout, so no test was lost

  • minimum versions raised to the current releases: python-libsbml>=5.21.1, antimony>=3.1.3, pint>=0.25.3, markdown-it-py>=4.2.0, pymetadata>=0.6.0, pydantic>=2.13.5, requests>=2.34.2 and, in the cytoscape extra, py4cytoscape>=1.13.0

Fixes

  • SBMLDocumentInfo._get_pk raised a NameError whenever the primary key was already cached on an element: it returned a variable which is only bound in the branch which computes it
  • comp._create_port called factory.UnitDefinition.get_unit_string, which does not exist, so creating a port for a unit raised an AttributeError. The unit reference is the id of the unit definition and is set directly
  • fbc.cobra called reactions.get_by_sid and reaction.getId(), neither of which is cobrapy API, so cobra_reaction_info and check_mass_balance failed on the first reaction, and the unbalanced reactions were logged as a format string
  • ExternalAnnotation never uppercased the qualifier of an annotation file, the key it compared against was misspelled as qualifer
  • the CompartmentGlyph of the layout package declared its glyph as a SpeciesGlyph, copied from the class above it
  • libsbml.FBC_FBCVARIABLETYPE_LINEAR does not exist, the constant is FBC_VARIABLE_TYPE_LINEAR
  • UnitDefinition._create_unit declared the unit kind as a str, the libsbml kinds are integers
  • an error while creating an SBML object reported an unbound variable (UnboundLocalError) instead of the object which failed
  • visualize_antimony leaked a NamedTemporaryFile which was never closed
  • the deprecated Thread.setDaemon, tempfile.mktemp and pydantic .dict() calls are replaced
  • the downloads of sbmlutils.biomodels retry the transient error responses (429, 500, 502, 503, 504) with an exponential backoff and time out after 30 seconds, instead of failing on the first hiccup of the BioModels service. They use the shared session of pymetadata rather than a second copy of it, and query_curated_biomodels goes through it as well
  • the XPP converter is documented and covered for every packaged ode file (#213): 112836_HH-ext and SkM_AP_KCa were commented out of tests/converters/test_xpp.py, both convert to models which validate without an error or a warning. They do not integrate with the default solver of roadrunner, which is a property of those stiff models rather than of the conversion, see Converters

Features

  • no example opens a GUI window any more. A plotting example builds its figure, returns it and writes it to a file, which blocked the test suite on a machine with a display and failed on one without; the conftest.py at the root selects the non-interactive Agg backend for the test session and the example scripts run with MPLBACKEND=Agg
  • no example writes into the repository or into the package: the models, the figures and the generated code go into the current working directory
  • tests/examples/test_example_scripts.py runs the examples which convert, merge, interpolate or simulate in a temporary working directory, so an example which breaks fails the test suite. examples/fbc/fbc_userdefinedconstraints.py is part of the tested examples now, which is how its TypeError surfaced

Documentation

  • the documentation is built and published again (#448), migrated from sphinx to Zensical, the static site generator of the Material for MkDocs authors: markdown sources in docs/, configured in zensical.toml, built and published to https://matthiaskoenig.github.io/sbmlutils by a GitHub workflow on every push to develop. Nothing rendered is committed and docs_builder/ is gone
  • new user guides for model creation, units, annotations, notes, validation, reading and writing, model composition, flux balance constraints, distributions and uncertainties, COMBINE archives, reports, converters, interpolation and visualization. Every code block was run against the package. This covers model creation with its objects, annotation, model import and merging (#408) and the comp package with ports, submodels, replacements and flattening (#214)
  • API reference of 29 modules, rendered from the docstrings by mkdocstrings
  • the documentation is available as markdown for agents and language models: llms.txt, llms-full.txt and every page next to its html. CLAUDE.md describes the repository itself
  • examples/README.md describes what is where and how to run it
  • a References page cites the publications of SBML Level 3, of the Level 3 Version 2 core specification and of the fbc and distrib packages, and the guides link to the paper of the package they describe
  • the presentations moved from docs/presentations/ to presentations/, since docs/ is the documentation source now

Development

  • mypy replaced by ty for type checking (#465); ty runs in CI, in tox r -e ty and as a pre-commit hook. All 65 # type: ignore comments are gone and the tree is at zero diagnostics, which is what surfaced most of the fixes above. Annotations are accepted as a Sequence rather than a list, so passing the list[tuple[BQB, str]] a model definition naturally writes is no longer an error at every call site
  • more ruff rules (import sorting, docstrings, pyupgrade, bugbear, comprehensions, simplifications, returns, logging format) and additional pre-commit hooks (toml, json, case conflicts, line endings, forgotten debug statements). The blanket F403/F405 ignore of the star imports became a per file ignore of the model definitions which need them; log calls use lazy %s formatting instead of f-strings
  • type annotations modernized to dict, list and X | None, mutable class attributes marked as ClassVar
  • the project urls reach the metadata now: the table was written as [project_urls] instead of [project.urls], so it was silently ignored and the pypi page carried no links at all. Documentation points to the documentation site and a Changelog url was added. The license metadata follows PEP 639, i.e., license = "MIT" with license-files, instead of the deprecated License :: classifier
  • root configuration cleaned up: the dev and test extras are merged into one dev extra, the pytest configuration moved from tox.ini to [tool.pytest.ini_options] in pyproject.toml, the unused pytest-raises dependency and its raises marker are gone, as is the install tox environment which nothing referenced. MANIFEST.in was removed, hatchling does not read it and it referred to a README.rst which no longer exists, and RELEASE.md moved into the documentation
  • the workflows pin their actions, declare least privilege permissions, cancel superseded runs and time out; the test matrix covers linux, windows and macos and the release job publishes with trusted publishing. main.yml became ci-cd.yml and mypy.yml became ty.yml; dependabot keeps the actions current
  • CITATION.cff added and bumped with the version, .gitignore lost the entries of tools which are not used and the stale build/ and src/sbmlutils.egg-info/ artifacts of setuptools are gone

Your sbmlutils team