pymetadata 0.8.0__tar.gz → 0.8.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.bumpversion.toml +1 -1
- pymetadata-0.8.2/.github/dependabot.yml +34 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.github/workflows/ci-cd.yml +17 -24
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.github/workflows/docs.yml +12 -4
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.github/workflows/ruff.yml +4 -1
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.github/workflows/ty.yml +1 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.gitignore +5 -2
- {pymetadata-0.8.0 → pymetadata-0.8.2}/CITATION.cff +2 -2
- {pymetadata-0.8.0 → pymetadata-0.8.2}/CLAUDE.md +22 -13
- {pymetadata-0.8.0 → pymetadata-0.8.2}/PKG-INFO +8 -7
- {pymetadata-0.8.0 → pymetadata-0.8.2}/README.md +5 -5
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/development.md +8 -2
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/index.md +5 -5
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/installation.md +7 -1
- {pymetadata-0.8.0 → pymetadata-0.8.2}/pyproject.toml +4 -1
- pymetadata-0.8.2/release-notes/0.8.1.md +20 -0
- pymetadata-0.8.2/release-notes/0.8.2.md +9 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/__init__.py +1 -1
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/cache.py +125 -26
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/webservices/chebi.py +5 -18
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/webservices/registry.py +23 -9
- pymetadata-0.8.2/tests/data/registry/identifiers_registry_response.json +596 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_cache.py +123 -0
- pymetadata-0.8.2/tests/test_registry.py +231 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tox.ini +3 -1
- pymetadata-0.8.2/uv.lock +1669 -0
- pymetadata-0.8.0/.github/dependabot.yml +0 -16
- pymetadata-0.8.0/tests/test_registry.py +0 -11
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.github/CODEOWNERS +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.github/pull_request_template.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.github/rulesets/apply.sh +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.github/rulesets/develop.json +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.github/rulesets/main.json +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.github/rulesets/tags.json +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.pre-commit-config.yaml +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.python-version +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.ruff.toml +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/.zenodo.json +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/LICENSE +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/README.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/annotations.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/cache.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/console.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/core.annotation.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/core.creator.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/core.miriam.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/core.xref.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/index.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/log.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/omex.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/ontologies.term.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/webservices.chebi.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/webservices.ols.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/webservices.registry.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/webservices.unichem.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/webservices.uniprot.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/api/webservices.webservice.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/HARMONY2026_slides.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/favicon/about.txt +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/favicon/android-chrome-192x192.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/favicon/android-chrome-512x512.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/favicon/apple-touch-icon.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/favicon/favicon-16x16.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/favicon/favicon-32x32.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/favicon/favicon.ico +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/favicon/favicon_io.zip +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/favicon/pymetadata-100x100-300dpi.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/images/favicon/site.webmanifest +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/omex.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/docs/robots.txt +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/annotation.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/cache_path.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/MODEL2402290004.4_pymetadata.omex +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/create_omex.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/BioModelsMetadata_MODEL2402290004.csv +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/EndoAcuteBZ1.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/EndoAcuteBZ2.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/EndoAcuteBZ3.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/EndoChronicBZ.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/EndoChronicRZ1.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/EndoChronicRZ2.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/EndoNZ.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/POM253.mat +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/PlotAPCaTTaAcuteAndChronic.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/Zhou2024_Updated-model.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/getCurrentsStructureCaMKSKJrelpKinetics.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/getStartingState.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/main.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/manifest.xml +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/metadata.rdf +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/modelRunnerCaMKSKJrelpKinetics1ms.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/biomodels_omex/files/model_ToRORd_LandCaMKSKJrelpKinetics.m +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/omex.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/omex_from_url.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/omex/test.omex +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/pbpko.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/examples/sbo.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/.gitignore +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/README.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/_extensions/grantmcdermott/clean/_extension.yml +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/_extensions/grantmcdermott/clean/clean.scss +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/_extensions/grantmcdermott/clean/mathjax-config.js +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/custom.scss +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/images/annotation_example.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/images/annotation_resolved.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/images/annotation_resolved_small.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/images/github_screenshot.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/images/headshot.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/images/omex_logo.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/images/omex_overview.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/images/pymetadata.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/images/pymetadata_large.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/images/qr_livermetabolism.png +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/mathjax-config.js +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/pymetadata.bib +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/pymetadata.qmd +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/presentations/HARMONY2026/styles.css +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.10.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.11.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.12.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.13.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.14.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.15.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.16.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.17.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.18.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.19.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.2.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.20.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.21.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.22.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.3.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.4.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.5.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.6.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.7.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.8.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.0.9.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.1.0.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.2.1.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.2.10.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.2.2.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.2.3.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.2.4.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.2.5.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.2.6.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.2.7.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.2.8.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.2.9.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.0.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.1.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.10.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.11.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.2.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.3.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.4.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.5.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.6.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.7.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.8.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.3.9.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.4.0.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.4.1.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.4.2.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.4.3.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.4.4.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.0.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.1.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.10.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.11.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.12.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.2.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.3.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.4.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.5.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.6.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.7.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.8.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.5.9.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.6.0.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.6.1.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.6.2.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.6.3.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.6.4.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.6.5.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.6.6.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.7.0.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/release-notes/0.8.0.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/scripts/llms_txt.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/_files.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/console.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/core/__init__.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/core/annotation.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/core/creator.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/core/miriam.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/core/synonym.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/core/xref.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/log.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/omex.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/ontologies/__init__.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/ontologies/_ontology_builder.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/ontologies/kisao.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/ontologies/pbpko.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/ontologies/sbo.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/ontologies/term.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/py.typed +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/resources/ontologies/README.md +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/webservices/__init__.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/webservices/ols.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/webservices/unichem.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/webservices/uniprot.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/src/pymetadata/webservices/webservice.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/core/test_annotation.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/core/test_creator.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/data/omex/BIOMD0000000001.omex +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/data/omex/CombineArchiveShowCase.omex +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/data/omex/CombineArchiveShowCase_manifest.xml +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/data/omex/CompModels.omex +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/data/omex/CompModels_manifest.xml +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/data/omex/iCGB21FR.omex +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_annotation_resolution.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_chebi.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_log.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_offline.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_ols.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_omex.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_ontology.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_ontology_builder.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_sbo_kisao.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_unichem.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_uniprot.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/tests/test_webservice.py +0 -0
- {pymetadata-0.8.0 → pymetadata-0.8.2}/zensical.toml +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Keep the GitHub Actions used in the workflows and the locked python dependencies up to date,
|
|
2
|
+
# monthly, since every update pull request runs the checks.
|
|
3
|
+
# See https://docs.github.com/code-security/dependabot/dependabot-version-updates
|
|
4
|
+
version: 2
|
|
5
|
+
updates:
|
|
6
|
+
- package-ecosystem: "github-actions"
|
|
7
|
+
directory: "/"
|
|
8
|
+
schedule:
|
|
9
|
+
interval: "monthly"
|
|
10
|
+
# a single pull request for all action updates instead of one per action
|
|
11
|
+
groups:
|
|
12
|
+
github-actions:
|
|
13
|
+
patterns:
|
|
14
|
+
- "*"
|
|
15
|
+
open-pull-requests-limit: 5
|
|
16
|
+
commit-message:
|
|
17
|
+
prefix: "ci"
|
|
18
|
+
|
|
19
|
+
# the locked python dependencies (uv.lock), bumped together
|
|
20
|
+
- package-ecosystem: "uv"
|
|
21
|
+
directory: "/"
|
|
22
|
+
# only uv.lock is updated: the default would raise the lower bounds in
|
|
23
|
+
# pyproject.toml, which are what a user of the library installs against,
|
|
24
|
+
# so they are only ever changed by hand
|
|
25
|
+
versioning-strategy: lockfile-only
|
|
26
|
+
schedule:
|
|
27
|
+
interval: "monthly"
|
|
28
|
+
groups:
|
|
29
|
+
python-dependencies:
|
|
30
|
+
patterns:
|
|
31
|
+
- "*"
|
|
32
|
+
open-pull-requests-limit: 5
|
|
33
|
+
commit-message:
|
|
34
|
+
prefix: "build"
|
|
@@ -15,8 +15,9 @@ permissions:
|
|
|
15
15
|
|
|
16
16
|
concurrency:
|
|
17
17
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
18
|
-
#
|
|
19
|
-
|
|
18
|
+
# a newer run supersedes the running one of the same branch or pull request;
|
|
19
|
+
# a release is never superseded, every tag is a group of its own
|
|
20
|
+
cancel-in-progress: true
|
|
20
21
|
|
|
21
22
|
jobs:
|
|
22
23
|
test:
|
|
@@ -25,26 +26,11 @@ jobs:
|
|
|
25
26
|
strategy:
|
|
26
27
|
fail-fast: false
|
|
27
28
|
matrix:
|
|
29
|
+
# continuous integration tests the newest python on every platform, the
|
|
30
|
+
# older and newer versions are tested locally with `tox run-parallel`,
|
|
31
|
+
# see docs/development.md
|
|
28
32
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
29
|
-
python-version: ["3.
|
|
30
|
-
# linux covers the full range, windows and macos only the newest version
|
|
31
|
-
exclude:
|
|
32
|
-
- os: windows-latest
|
|
33
|
-
python-version: "3.11"
|
|
34
|
-
- os: windows-latest
|
|
35
|
-
python-version: "3.12"
|
|
36
|
-
- os: windows-latest
|
|
37
|
-
python-version: "3.13"
|
|
38
|
-
- os: windows-latest
|
|
39
|
-
python-version: "3.14"
|
|
40
|
-
- os: macos-latest
|
|
41
|
-
python-version: "3.11"
|
|
42
|
-
- os: macos-latest
|
|
43
|
-
python-version: "3.12"
|
|
44
|
-
- os: macos-latest
|
|
45
|
-
python-version: "3.13"
|
|
46
|
-
- os: macos-latest
|
|
47
|
-
python-version: "3.14"
|
|
33
|
+
python-version: ["3.14"]
|
|
48
34
|
|
|
49
35
|
steps:
|
|
50
36
|
- uses: actions/checkout@v7
|
|
@@ -55,10 +41,16 @@ jobs:
|
|
|
55
41
|
uses: astral-sh/setup-uv@v10.2.0
|
|
56
42
|
with:
|
|
57
43
|
python-version: ${{ matrix.python-version }}
|
|
58
|
-
|
|
44
|
+
# a release run restores no cache, which zizmor cannot tell from the
|
|
45
|
+
# expression; the distributions are built without one, see `release`
|
|
46
|
+
enable-cache: ${{ !startsWith(github.ref, 'refs/tags/') }} # zizmor: ignore[cache-poisoning]
|
|
47
|
+
# the interpreter is cached with the packages instead of downloaded by every run
|
|
48
|
+
cache-python: ${{ !startsWith(github.ref, 'refs/tags/') }} # zizmor: ignore[cache-poisoning]
|
|
59
49
|
- name: Test with tox
|
|
50
|
+
# the runner is billed by wall time: the tests run on every core, the
|
|
51
|
+
# slowest are listed so they stay visible
|
|
60
52
|
run:
|
|
61
|
-
uvx --with tox-uv tox -e py${{ matrix.python-version }}
|
|
53
|
+
uvx --with tox-uv tox -e py${{ matrix.python-version }} -- -n auto --durations=15
|
|
62
54
|
|
|
63
55
|
tests:
|
|
64
56
|
# the one check the branch protection requires; the names of the matrix
|
|
@@ -95,7 +87,8 @@ jobs:
|
|
|
95
87
|
uses: astral-sh/setup-uv@v10.2.0
|
|
96
88
|
with:
|
|
97
89
|
python-version: "3.14"
|
|
98
|
-
|
|
90
|
+
# a release is built from a clean state, never from a restored cache
|
|
91
|
+
enable-cache: false
|
|
99
92
|
- name: Build package
|
|
100
93
|
run: uvx hatch build
|
|
101
94
|
- name: Check the package
|
|
@@ -13,8 +13,9 @@ permissions:
|
|
|
13
13
|
|
|
14
14
|
concurrency:
|
|
15
15
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
16
|
-
#
|
|
17
|
-
|
|
16
|
+
# a newer run supersedes the running one; a cancelled deployment leaves the
|
|
17
|
+
# published site as it was, the newer run deploys
|
|
18
|
+
cancel-in-progress: true
|
|
18
19
|
|
|
19
20
|
jobs:
|
|
20
21
|
docs:
|
|
@@ -27,14 +28,19 @@ jobs:
|
|
|
27
28
|
with:
|
|
28
29
|
persist-credentials: false
|
|
29
30
|
- name: Configure GitHub Pages
|
|
31
|
+
# only needed for the deployment, see `deploy`
|
|
32
|
+
if: github.ref == 'refs/heads/develop'
|
|
30
33
|
uses: actions/configure-pages@v6
|
|
31
34
|
- name: Install uv and set the python version
|
|
32
35
|
uses: astral-sh/setup-uv@v10.2.0
|
|
33
36
|
with:
|
|
34
37
|
python-version: "3.14"
|
|
35
38
|
enable-cache: true
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
cache-python: true
|
|
40
|
+
- name: Install the locked dependencies (fails if uv.lock is out of date with pyproject.toml, run `uv lock`)
|
|
41
|
+
# `--locked` refuses to update the lock: a change of the dependencies
|
|
42
|
+
# in pyproject.toml has to come with the `uv lock` which records it
|
|
43
|
+
run: uv sync --locked --extra dev
|
|
38
44
|
- name: Build the documentation
|
|
39
45
|
# the API reference is rendered from the docstrings by mkdocstrings,
|
|
40
46
|
# so the package has to be importable
|
|
@@ -43,6 +49,8 @@ jobs:
|
|
|
43
49
|
# llms.txt, llms-full.txt and the markdown of every page
|
|
44
50
|
run: uv run python scripts/llms_txt.py
|
|
45
51
|
- name: Upload the site
|
|
52
|
+
# only needed for the deployment, see `deploy`
|
|
53
|
+
if: github.ref == 'refs/heads/develop'
|
|
46
54
|
uses: actions/upload-pages-artifact@v5
|
|
47
55
|
with:
|
|
48
56
|
path: site
|
|
@@ -25,13 +25,16 @@ jobs:
|
|
|
25
25
|
- uses: actions/checkout@v7
|
|
26
26
|
with:
|
|
27
27
|
persist-credentials: false
|
|
28
|
-
# the ruff version is read from the
|
|
28
|
+
# the ruff version is read from the lock (the same file `uv run ruff` uses locally), not from the
|
|
29
|
+
# `ruff>=` bound in pyproject.toml, which would resolve to the latest release
|
|
29
30
|
- name: Lint
|
|
30
31
|
# astral-sh/ruff-action publishes no floating major tag beyond v3
|
|
31
32
|
uses: astral-sh/ruff-action@v4.1.0
|
|
32
33
|
with:
|
|
34
|
+
version-file: uv.lock
|
|
33
35
|
args: check --output-format=github
|
|
34
36
|
- name: Format
|
|
35
37
|
uses: astral-sh/ruff-action@v4.1.0
|
|
36
38
|
with:
|
|
39
|
+
version-file: uv.lock
|
|
37
40
|
args: format --check --diff
|
|
@@ -17,8 +17,11 @@ coverage.xml
|
|
|
17
17
|
# rendered documentation, built by the `documentation` workflow
|
|
18
18
|
site/
|
|
19
19
|
|
|
20
|
-
#
|
|
21
|
-
|
|
20
|
+
# working files of coding agents, their design documents and plans are not committed
|
|
21
|
+
.superpowers/
|
|
22
|
+
docs/superpowers/
|
|
23
|
+
.claude/plans/
|
|
24
|
+
.claude/specs/
|
|
22
25
|
|
|
23
26
|
# editors, operating system
|
|
24
27
|
.idea/
|
|
@@ -8,8 +8,8 @@ authors:
|
|
|
8
8
|
given-names: "Matthias"
|
|
9
9
|
orcid: "https://orcid.org/0000-0003-1725-179X"
|
|
10
10
|
affiliation: "Humboldt-University Berlin, Faculty of Life Science, Institute for Biology, Biology, Berlin; University Lübeck; University Hospital Schleswig-Holstein, Campus Lübeck, First Department of Medicine, Germany"
|
|
11
|
-
version: "0.8.
|
|
12
|
-
date-released: "2026-
|
|
11
|
+
version: "0.8.2"
|
|
12
|
+
date-released: "2026-10-05"
|
|
13
13
|
doi: "10.5281/zenodo.5308801"
|
|
14
14
|
license: MIT
|
|
15
15
|
repository-code: "https://github.com/matthiaskoenig/pymetadata"
|
|
@@ -4,12 +4,7 @@ This file provides guidance when working with code in this repository.
|
|
|
4
4
|
|
|
5
5
|
## Project
|
|
6
6
|
|
|
7
|
-
`pymetadata` is a python library for metadata in the context of COMBINE standards:
|
|
8
|
-
COMBINE archives (OMEX), MIRIAM/RDF annotations, and ontology terms (SBO, KISAO, PBPKO).
|
|
9
|
-
Pure library, no CLI entry points. Requires python >= 3.11, packaged with hatchling
|
|
10
|
-
(version is read from `src/pymetadata/__init__.py`). Runtime dependencies are
|
|
11
|
-
`rich`, `requests` and `pydantic`; `pronto` is the optional `ontology` extra,
|
|
12
|
-
needed only to regenerate the ontology modules.
|
|
7
|
+
`pymetadata` is a python library for metadata in the context of COMBINE standards: COMBINE archives (OMEX), MIRIAM/RDF annotations, and ontology terms (SBO, KISAO, PBPKO). Pure library, no CLI entry points. Requires python >= 3.11, packaged with hatchling (version is read from `src/pymetadata/__init__.py`). Runtime dependencies are `rich`, `requests` and `pydantic`, plus the floors of `urllib3` and `certifi`, which are not imported but reached through `requests` (`certifi>=2026.10.19` excludes the CA store with the compromised emSign intermediates, GHSA-6q48-6c7w-9gw2); `pronto` is the optional `ontology` extra, needed only to regenerate the ontology modules.
|
|
13
8
|
|
|
14
9
|
## Commands
|
|
15
10
|
|
|
@@ -17,13 +12,14 @@ needed only to regenerate the ontology modules.
|
|
|
17
12
|
# environment (uv based); the dev extra includes the ontology extra
|
|
18
13
|
uv sync --extra dev
|
|
19
14
|
uv run pre-commit install
|
|
15
|
+
uv lock # after every change of a dependency in pyproject.toml
|
|
20
16
|
|
|
21
17
|
# tests
|
|
22
18
|
pytest # all tests
|
|
23
19
|
pytest tests/test_omex.py # single file
|
|
24
20
|
pytest tests/test_omex.py::test_entry_from_dict # single test
|
|
25
21
|
tox r -e py3.15 # single tox env (py3.11-3.15 available)
|
|
26
|
-
tox run-parallel # full matrix + ty
|
|
22
|
+
tox run-parallel # full matrix + ty, run before opening a pull request
|
|
27
23
|
|
|
28
24
|
# lint / format / types
|
|
29
25
|
ruff check
|
|
@@ -32,11 +28,7 @@ tox -e ty # ty type check (config in [tool.ty] in pyprojec
|
|
|
32
28
|
uvx ty check # same check, straight from the working tree
|
|
33
29
|
```
|
|
34
30
|
|
|
35
|
-
`develop` is the default branch and takes every change through a pull request;
|
|
36
|
-
direct pushes are rejected by the rulesets in `.github/rulesets/` (applied with
|
|
37
|
-
`.github/rulesets/apply.sh`), which require the `tests`, `ruff`, `ty` and `docs`
|
|
38
|
-
checks. `main` only tracks the latest release and is fast-forwarded by the
|
|
39
|
-
`sync-main` job of the release workflow, never by hand.
|
|
31
|
+
`develop` is the default branch and takes every change through a pull request; direct pushes are rejected by the rulesets in `.github/rulesets/` (applied with `.github/rulesets/apply.sh`), which require the `tests`, `ruff`, `ty` and `docs` checks. Continuous integration is kept minimal: `tests` runs only `py3.14`, on linux, macos and windows, with pytest-xdist (`-n auto`), every workflow cancels a superseded run (`cancel-in-progress: true`), uv caches packages and interpreters, dependabot runs monthly. The other python versions run only locally. `main` only tracks the latest release and is fast-forwarded by the `sync-main` job of the release workflow, never by hand.
|
|
40
32
|
|
|
41
33
|
Release steps are in `docs/development.md` (there is no separate `RELEASE.md`):
|
|
42
34
|
the release is prepared on a branch, `uvx bump-my-version bump [major|minor|patch]`
|
|
@@ -121,7 +113,14 @@ registry). When a refresh fails, `read_json_cache_fallback` returns the outdated
|
|
|
121
113
|
content with a warning instead of failing, so queries answered before keep
|
|
122
114
|
working offline; `tests/test_offline.py` covers this per service. The corresponding tests
|
|
123
115
|
(`test_ols.py`, `test_registry.py`, `test_chebi.py`, `test_unichem.py`, `test_uniprot.py`) require
|
|
124
|
-
network access.
|
|
116
|
+
network access. Processes share the cache (pytest-xdist workers): `write_bytes_cache`
|
|
117
|
+
and `write_json_cache` write a temporary file next to the cache file and `os.replace`
|
|
118
|
+
it, so a reader never sees a partial file, and the write is best effort, a failure is
|
|
119
|
+
a warning and the caller keeps its data. On Windows a file another process has open
|
|
120
|
+
cannot be replaced and a file being replaced cannot be opened, so both are retried
|
|
121
|
+
(`CACHE_IN_USE_ATTEMPTS`); `Registry` uses the downloaded namespaces and does not read
|
|
122
|
+
them back. `test_registry.py` loads the registry from several processes into one empty
|
|
123
|
+
cache, with the download answered from `tests/data/registry/` (#102).
|
|
125
124
|
|
|
126
125
|
`console.py` (rich console, for scripts and `__main__` blocks) and `log.py`
|
|
127
126
|
provide the shared output/logging. Modules get their logger from the standard
|
|
@@ -138,6 +137,16 @@ lazy `%s` formatting rather than f-strings (enforced by ruff `G`).
|
|
|
138
137
|
`project.requires-python`. Suppress a diagnostic with a rule-specific
|
|
139
138
|
`# ty: ignore[rule-name]`, never a blanket `# type: ignore`. ty also runs as a
|
|
140
139
|
pre-commit hook (`--extra dev`, so the hook syncs the dev environment it checks against).
|
|
140
|
+
- `uv.lock` is committed and pins the local development environment (`uv sync`,
|
|
141
|
+
`uv run`, so also `uv run ty check`), the `documentation` workflow, which runs
|
|
142
|
+
`uv sync --locked`, and the ruff version of the `ruff` workflow; the tox
|
|
143
|
+
environments, i.e. the test matrix and the `ty` check of continuous
|
|
144
|
+
integration, resolve from `pyproject.toml` and do not use it. After changing a
|
|
145
|
+
dependency in `pyproject.toml` run `uv lock`, otherwise the `documentation`
|
|
146
|
+
workflow fails; `uv lock --upgrade` moves the lock to the newest releases.
|
|
147
|
+
Dependabot bumps the lock monthly with `versioning-strategy: lockfile-only`, so
|
|
148
|
+
the lower bounds in `pyproject.toml`, which users install against, are only
|
|
149
|
+
changed by hand.
|
|
141
150
|
- Every module, class and function carries full type annotations and a google-style
|
|
142
151
|
docstring.
|
|
143
152
|
- `examples/` at the top level holds the runnable usage examples, they are not
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pymetadata
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.2
|
|
4
4
|
Summary: pymetadata are python utilities for working with metadata.
|
|
5
5
|
Project-URL: Homepage, https://matthiaskoenig.github.io/pymetadata
|
|
6
6
|
Project-URL: Documentation, https://matthiaskoenig.github.io/pymetadata
|
|
@@ -25,7 +25,8 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
|
25
25
|
Classifier: Topic :: Scientific/Engineering
|
|
26
26
|
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
27
27
|
Requires-Python: >=3.11
|
|
28
|
-
Requires-Dist:
|
|
28
|
+
Requires-Dist: certifi>=2026.10.19
|
|
29
|
+
Requires-Dist: pydantic>=2.12
|
|
29
30
|
Requires-Dist: requests>=2.34.2
|
|
30
31
|
Requires-Dist: rich>=15.0.0
|
|
31
32
|
Requires-Dist: urllib3>=2.5.0
|
|
@@ -65,18 +66,18 @@ If you have any questions or issues please [open an issue](https://github.com/ma
|
|
|
65
66
|
|
|
66
67
|
If you use `pymetadata` please cite the archived software on [Zenodo](https://doi.org/10.5281/zenodo.5308801):
|
|
67
68
|
|
|
68
|
-
> König, M. (2026). *pymetadata are python utilities for working with metadata* (Version 0.
|
|
69
|
+
> König, M. (2026). *pymetadata are python utilities for working with metadata* (Version 0.8.0) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.23159552
|
|
69
70
|
|
|
70
71
|
```bibtex
|
|
71
72
|
@software{konig_pymetadata,
|
|
72
73
|
author = {König, Matthias},
|
|
73
74
|
title = {pymetadata are python utilities for working with metadata},
|
|
74
75
|
year = {2026},
|
|
75
|
-
month =
|
|
76
|
-
version = {0.
|
|
76
|
+
month = oct,
|
|
77
|
+
version = {0.8.0},
|
|
77
78
|
publisher = {Zenodo},
|
|
78
|
-
doi = {10.5281/zenodo.
|
|
79
|
-
url = {https://doi.org/10.5281/zenodo.
|
|
79
|
+
doi = {10.5281/zenodo.23159552},
|
|
80
|
+
url = {https://doi.org/10.5281/zenodo.23159552},
|
|
80
81
|
}
|
|
81
82
|
```
|
|
82
83
|
|
|
@@ -19,18 +19,18 @@ If you have any questions or issues please [open an issue](https://github.com/ma
|
|
|
19
19
|
|
|
20
20
|
If you use `pymetadata` please cite the archived software on [Zenodo](https://doi.org/10.5281/zenodo.5308801):
|
|
21
21
|
|
|
22
|
-
> König, M. (2026). *pymetadata are python utilities for working with metadata* (Version 0.
|
|
22
|
+
> König, M. (2026). *pymetadata are python utilities for working with metadata* (Version 0.8.0) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.23159552
|
|
23
23
|
|
|
24
24
|
```bibtex
|
|
25
25
|
@software{konig_pymetadata,
|
|
26
26
|
author = {König, Matthias},
|
|
27
27
|
title = {pymetadata are python utilities for working with metadata},
|
|
28
28
|
year = {2026},
|
|
29
|
-
month =
|
|
30
|
-
version = {0.
|
|
29
|
+
month = oct,
|
|
30
|
+
version = {0.8.0},
|
|
31
31
|
publisher = {Zenodo},
|
|
32
|
-
doi = {10.5281/zenodo.
|
|
33
|
-
url = {https://doi.org/10.5281/zenodo.
|
|
32
|
+
doi = {10.5281/zenodo.23159552},
|
|
33
|
+
url = {https://doi.org/10.5281/zenodo.23159552},
|
|
34
34
|
}
|
|
35
35
|
```
|
|
36
36
|
|
|
@@ -27,7 +27,7 @@ A pull request can only be merged once the four required checks are green:
|
|
|
27
27
|
|
|
28
28
|
| check | workflow | content |
|
|
29
29
|
| ------- | ------------- | -------------------------------------------------------------------- |
|
|
30
|
-
| `tests` | `ci-cd.yml` | the test matrix, linux, macos and windows
|
|
30
|
+
| `tests` | `ci-cd.yml` | the test matrix, python 3.14 on linux, macos and windows |
|
|
31
31
|
| `ruff` | `ruff.yml` | `ruff check` and `ruff format --check` |
|
|
32
32
|
| `ty` | `ty.yml` | `tox r -e ty` |
|
|
33
33
|
| `docs` | `docs.yml` | the zensical build including the api reference and the agent files |
|
|
@@ -35,6 +35,8 @@ A pull request can only be merged once the four required checks are green:
|
|
|
35
35
|
`tests` aggregates the test matrix into a single job, so the name of the
|
|
36
36
|
required check stays the same when the matrix changes.
|
|
37
37
|
|
|
38
|
+
Continuous integration is kept small: every workflow cancels its running build when a newer commit of the same branch or pull request arrives, uv caches the packages and the interpreters between runs, dependabot proposes its updates once a month, and the matrix tests only python 3.14. The other python versions are tested locally, see [Testing](#testing), before a pull request is opened.
|
|
39
|
+
|
|
38
40
|
Further rules of a pull request:
|
|
39
41
|
|
|
40
42
|
- conversations have to be resolved before the merge
|
|
@@ -94,6 +96,8 @@ A single sync creates the virtual environment in `.venv`, installs `pymetadata`
|
|
|
94
96
|
uv sync --extra dev
|
|
95
97
|
```
|
|
96
98
|
|
|
99
|
+
The environment is resolved from `uv.lock`, which is committed, so local development, including `uv run ty check`, and the documentation build use the same versions. The tox environments, i.e. the test matrix and the `ty` check of continuous integration, resolve from `pyproject.toml` and do not use the lock; the lower bounds in `pyproject.toml` are what a user of the library installs against. After changing a dependency in `pyproject.toml` run `uv lock`: the `documentation` workflow syncs with `uv sync --locked`, which fails when `pyproject.toml` and the lock disagree. `uv lock --upgrade` moves the lock to the newest releases. Dependabot bumps the locked dependencies as one grouped monthly pull request, with `versioning-strategy: lockfile-only`, so the lower bounds in `pyproject.toml` are never raised by it and only ever changed by hand.
|
|
100
|
+
|
|
97
101
|
The `dev` extra contains everything used below, i.e., pytest, ruff, ty, tox, pre-commit, zensical and bump-my-version, and it pulls in the optional `ontology` extra, so nothing has to be installed separately. The python version is taken from `.python-version` (currently 3.14); to work against the oldest supported version instead use `uv sync --extra dev --python 3.11`, which replaces the environment.
|
|
98
102
|
|
|
99
103
|
The tools are then run either with `uv run <command>`, which uses the environment without activating it, or from the activated environment:
|
|
@@ -127,7 +131,7 @@ and the complete matrix, including the `ty` environment, in parallel with
|
|
|
127
131
|
tox run-parallel
|
|
128
132
|
```
|
|
129
133
|
|
|
130
|
-
This needs the interpreters to be available, which uv installs with `uv python install 3.11 3.12 3.13 3.14 3.15`.
|
|
134
|
+
This needs the interpreters to be available, which uv installs with `uv python install 3.11 3.12 3.13 3.14 3.15`. It is the complete test and is run before a pull request is opened: continuous integration runs only `py3.14`, on linux, macos and windows, as `uvx --with tox-uv tox -e py3.14 -- -n auto --durations=15`, i.e., with the tests distributed over the cores of the runner by pytest-xdist and the 15 slowest tests listed. What follows `--` is passed on to pytest, so `tox r -e py3.14 -- -n auto` does the same locally.
|
|
131
135
|
|
|
132
136
|
To run the tests directly against the development environment use
|
|
133
137
|
|
|
@@ -148,6 +152,8 @@ ruff check # lint
|
|
|
148
152
|
ruff format # format
|
|
149
153
|
```
|
|
150
154
|
|
|
155
|
+
The `ruff` workflow installs the ruff version locked in `uv.lock`, so continuous integration and `uv run ruff` agree.
|
|
156
|
+
|
|
151
157
|
## Type checking
|
|
152
158
|
|
|
153
159
|
Type checking is performed with [ty](https://docs.astral.sh/ty/):
|
|
@@ -70,18 +70,18 @@ If you have any questions or issues please [open an issue](https://github.com/ma
|
|
|
70
70
|
|
|
71
71
|
If you use `pymetadata` please cite the archived software on [Zenodo](https://doi.org/10.5281/zenodo.5308801):
|
|
72
72
|
|
|
73
|
-
> König, M. (2026). *pymetadata are python utilities for working with metadata* (Version 0.
|
|
73
|
+
> König, M. (2026). *pymetadata are python utilities for working with metadata* (Version 0.8.0) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.23159552
|
|
74
74
|
|
|
75
75
|
```bibtex
|
|
76
76
|
@software{konig_pymetadata,
|
|
77
77
|
author = {König, Matthias},
|
|
78
78
|
title = {pymetadata are python utilities for working with metadata},
|
|
79
79
|
year = {2026},
|
|
80
|
-
month =
|
|
81
|
-
version = {0.
|
|
80
|
+
month = oct,
|
|
81
|
+
version = {0.8.0},
|
|
82
82
|
publisher = {Zenodo},
|
|
83
|
-
doi = {10.5281/zenodo.
|
|
84
|
-
url = {https://doi.org/10.5281/zenodo.
|
|
83
|
+
doi = {10.5281/zenodo.23159552},
|
|
84
|
+
url = {https://doi.org/10.5281/zenodo.23159552},
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Installation
|
|
2
2
|
|
|
3
|
-
`pymetadata` requires python >= 3.11 and is available from [pypi](https://pypi.python.org/pypi/pymetadata). It is pure python and tested with python 3.11 to 3.15 on Linux, macOS and Windows. The only compiled dependency is `pydantic-core`, which comes with [pydantic](https://docs.pydantic.dev/) and is installed from a wheel; for python 3.15 these wheels are part of pydantic 2.14, with an older pydantic it is built from source, which requires a Rust toolchain.
|
|
3
|
+
`pymetadata` requires python >= 3.11 and is available from [pypi](https://pypi.python.org/pypi/pymetadata). It is pure python and tested with python 3.11 to 3.15: continuous integration tests python 3.14 on Linux, macOS and Windows, all supported versions are tested locally on Linux before every pull request. The only compiled dependency is `pydantic-core`, which comes with [pydantic](https://docs.pydantic.dev/) and is installed from a wheel; for python 3.15 these wheels are part of pydantic 2.14, with an older pydantic it is built from source, which requires a Rust toolchain.
|
|
4
4
|
|
|
5
5
|
## With uv
|
|
6
6
|
|
|
@@ -103,6 +103,12 @@ Using the cache from 1080.0 h ago, it could not be refreshed:
|
|
|
103
103
|
|
|
104
104
|
A query which was answered before therefore keeps working offline. Only a query which was never cached fails: `ChebiQuery.query` and `OLSQuery.query_ols` report the problem in their result, `UnichemQuery` and `Registry` raise a `WebserviceError`.
|
|
105
105
|
|
|
106
|
+
### Several processes
|
|
107
|
+
|
|
108
|
+
Processes which run at the same time can share the cache, e.g., the workers of [pytest-xdist](https://pytest-xdist.readthedocs.io). A cache file is written to a temporary file in the same directory, which then replaces the cache file atomically, so a process never reads a partially written file. Processes which start on an empty cache each download what they need once, e.g., the registry.
|
|
109
|
+
|
|
110
|
+
Writing the cache is best effort, the process has the content already: a cache file which cannot be written is a warning, and the query returns its result anyway. On Windows a file which another process has open cannot be replaced, and a file which another process replaces cannot be opened; both are retried for about a second, after which the cache file of the other process is kept.
|
|
111
|
+
|
|
106
112
|
### The registry
|
|
107
113
|
|
|
108
114
|
The identifiers.org registry is cached independently of `CACHE_USE`. It is downloaded to `CACHE_PATH / "identifiers_registry.json"` and refreshed when the local copy is older than the cache duration:
|
|
@@ -41,7 +41,10 @@ dependencies = [
|
|
|
41
41
|
"rich>=15.0.0",
|
|
42
42
|
"requests>=2.34.2",
|
|
43
43
|
"urllib3>=2.5.0",
|
|
44
|
-
|
|
44
|
+
# not imported, reached through requests; the floor excludes the CA store
|
|
45
|
+
# with the compromised emSign intermediates, GHSA-6q48-6c7w-9gw2
|
|
46
|
+
"certifi>=2026.10.19",
|
|
47
|
+
"pydantic>=2.12",
|
|
45
48
|
]
|
|
46
49
|
|
|
47
50
|
[project.optional-dependencies]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Release notes for pymetadata 0.8.1
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
## Dependencies
|
|
5
|
+
|
|
6
|
+
- `pydantic>=2.12` instead of `pydantic>=2.13.5` (#105). The lower bound was the newest release when the bounds were pinned, not a requirement: the tests pass with pydantic 2.12.0 on python 3.11 and 3.14. The strict bound made pymetadata uninstallable with pip next to `pydantic-numpy` 9.0.2 (which requires `pydantic~=2.12.5`, and is the only release pip can install on python 3.14), e.g. in `sbmlsim[sciml]` through `petab-sciml`.
|
|
7
|
+
|
|
8
|
+
## Fixes
|
|
9
|
+
|
|
10
|
+
- Processes which load the identifiers.org registry into the same empty cache at the same time, e.g., the workers of pytest-xdist, no longer fail on Windows with `PermissionError: [WinError 5] Access is denied` (#102). A cache file which another process has open is retried for about a second, and a cache file which cannot be written is a warning instead of an error, the query returns its result anyway. `Registry` uses the namespaces it downloaded instead of reading them back from the cache.
|
|
11
|
+
- Reading a cache file which another process replaces at the same moment is retried on Windows.
|
|
12
|
+
- Cache files have the permissions of a regular file again (`0o666` minus the umask) instead of being readable only by their owner, so a cache directory can be shared.
|
|
13
|
+
- A corrupt cached registry is downloaded again instead of failing.
|
|
14
|
+
|
|
15
|
+
## Development
|
|
16
|
+
|
|
17
|
+
- The lock of the development environment, `uv.lock`, is tracked, and continuous integration installs it (#101).
|
|
18
|
+
- Continuous integration runs with less load (#104).
|
|
19
|
+
|
|
20
|
+
Your pymetadata team
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Release notes for pymetadata 0.8.2
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
## Security
|
|
5
|
+
|
|
6
|
+
- `certifi>=2026.10.19` is a runtime dependency (#106). certifi 2026.10.19 removes the emSign root CA, whose intermediates have compromised keys ([GHSA-6q48-6c7w-9gw2](https://github.com/advisories/GHSA-6q48-6c7w-9gw2)). pymetadata reaches the web services through `requests`, which verifies the certificates with the CA store of certifi, so the floor applies although certifi is not imported.
|
|
7
|
+
- The lock of the development environment, `uv.lock`, has certifi 2026.10.19 and virtualenv 21.14.12, which seeds pip 26.2.2 (vendoring certifi 2026.10.19) into the environments of tox (#106). uv is pinned nowhere: continuous integration installs the latest uv, 0.13.4 or newer, which fixes its bundled CA store ([GHSA-hq85-5cpj-mr62](https://github.com/advisories/GHSA-hq85-5cpj-mr62)); a local uv older than 0.13.4 should be updated.
|
|
8
|
+
|
|
9
|
+
Your pymetadata team
|