%global srcname pymetadata Name: python-%{srcname} Version: 0.8.0 Release: 1%{?dist} Summary: Metadata, annotations and COMBINE archives for systems-biology models License: MIT URL: https://github.com/matthiaskoenig/pymetadata Source: %{pypi_source %{srcname}} BuildArch: noarch BuildRequires: python3-devel BuildRequires: pyproject-rpm-macros # %%check BuildRequires: python3-pytest %global _description %{expand: pymetadata is Matthias Konig's metadata layer for the COMBINE standards: it reads and writes COMBINE archives (OMEX) with their manifest and metadata, models MIRIAM-qualified annotations as typed objects, resolves identifiers against the identifiers.org registry, and ships the SBO, KISAO and other ontology term sets as importable modules. Web-service lookups (identifiers.org, OLS, ChEBI, UniChem) are cached on disk, and an unreachable service falls back to the cached answer with a warning rather than an error, so an offline machine keeps working. It is the annotation layer sbmlutils builds on.} %description %_description %package -n python3-%{srcname} Summary: %{summary} %description -n python3-%{srcname} %_description %prep %autosetup -p1 -n %{srcname}-%{version} # Upstream's three runtime floors are the versions current on its release day, # not an API requirement: the whole surface it uses is BaseModel and # PrivateAttr from pydantic, Console, RichHandler and Theme from rich, and # requests.get with an adapter. All of it predates these floors by years. # Fedora 44 carries pydantic 2.12.5, rich 14.3.2 and requests 2.33.1, so the # floors as written would make the package unbuildable there and on 43. # %%check is the evidence that the relaxed floors hold: upstream's suite runs # against whatever the chroot actually has. for d in 'rich>=15.0.0:rich>=13' 'requests>=2.34.2:requests>=2.31' 'pydantic>=2.13.5:pydantic>=2'; do old=${d%%:*}; new=${d#*:} grep -q "\"$old\"," pyproject.toml || { echo "runtime floor '$old' not found" >&2; exit 1; } sed -i "s/\"$old\",/\"$new\",/" pyproject.toml done %generate_buildrequires %pyproject_buildrequires %build %pyproject_wheel %install %pyproject_install %pyproject_save_files -l %{srcname} %check # Upstream's suite, offline: 0.8.0 gives 189 pass, 136 deselected (0.6.6: 106 and 99). Every deselected case # belongs to a test function that asks a web service for an answer it does not # cache in the source tree, and a build root has no network: identifiers.org # for every resource normalisation, plus ChEBI, OLS, UniChem, and one OMEX # archive fetched from a GitHub release. Deselection is by function, so a few # parameter sets that happened to answer from cache go with them. # # What is left still covers the offline behaviour that matters here, including # test_offline.py, which asserts that an unreachable service falls back to # cached content rather than failing, and the whole OMEX archive layer. %pytest -q tests \ --deselect tests/test_chebi.py::test_chebi \ --deselect tests/test_ols.py::test_ols_query \ --deselect tests/test_ols.py::test_annotation_data_to_dict \ --deselect tests/test_registry.py::test_registry \ --deselect tests/test_unichem.py::test_get_sources \ --deselect tests/test_unichem.py::test_get_source_exists \ --deselect tests/test_unichem.py::test_get_source_missing \ --deselect tests/test_unichem.py::test_query_xref_for_inchikey_cache \ --deselect tests/test_unichem.py::test_query_xref_for_inchikey_no_cache \ --deselect tests/test_unichem.py::test_query_xrefs_server_error \ --deselect tests/test_omex.py::test_omex_from_url \ --deselect tests/core/test_annotation.py::test_rdf_annotation \ --deselect tests/core/test_annotation.py::test_check_term_pass \ --deselect tests/core/test_annotation.py::test_resource_normalized \ --deselect tests/core/test_annotation.py::test_resource_normalized_keeps_resource \ --deselect tests/core/test_annotation.py::test_resource_normalized_roundtrip \ --deselect tests/core/test_annotation.py::test_resource_normalized_registry \ --deselect tests/core/test_annotation.py::test_annotation_data_carries_the_ols_term \ --deselect tests/core/test_annotation.py::test_check_miriam_term_full_match \ --deselect tests/core/test_annotation.py::test_replaced_collection_before_shortening %files -n python3-%{srcname} -f %{pyproject_files} %doc README.md %changelog * Wed Oct 07 2026 Morgan Hough - 0.8.0-1 - Update to 0.8.0 (sbmlutils 0.16.0 requires pymetadata >= 0.8.0). The three relaxed runtime floors are unchanged and still match the sdist's pyproject. - Deselect five more cases that ask registry.api.identifiers.org (test_check_miriam_term_full_match, test_replaced_collection_before_shortening, test_annotation_data_carries_the_ols_term); a mock build root has no network. Offline on f44: 189 pass, 136 deselected, no failures. * Fri Sep 25 2026 Morgan Hough - 0.6.6-1 - Initial package: pymetadata 0.6.6, the COMBINE archive and annotation layer. Net-new to Fedora; pure Python, and the prerequisite sbmlutils is missing. - Relax three runtime floors that track upstream's release date rather than any API it uses; the upstream suite in %%check is the evidence. On Fedora 44 (pydantic 2.12.5, rich 14.3.2, requests 2.33.1) every offline case passes. - Deselect the test functions that query identifiers.org, ChEBI, OLS or UniChem, or fetch an archive over HTTP: 106 pass, 99 deselected. Running them offline cost 6m45s of DNS timeouts and 93 failures.