pymetadata 0.6.3__tar.gz → 0.6.4__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.6.3 → pymetadata-0.6.4}/.bumpversion.toml +1 -1
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/workflows/ci-cd.yml +2 -2
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/workflows/docs.yml +1 -1
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/workflows/ty.yml +1 -1
- {pymetadata-0.6.3 → pymetadata-0.6.4}/CITATION.cff +1 -1
- {pymetadata-0.6.3 → pymetadata-0.6.4}/PKG-INFO +1 -1
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/annotations.md +8 -0
- pymetadata-0.6.4/release-notes/0.6.4.md +13 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/__init__.py +1 -1
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/core/annotation.py +35 -20
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/omex.py +43 -24
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/core/test_annotation.py +79 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_omex.py +63 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/CODEOWNERS +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/dependabot.yml +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/pull_request_template.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/rulesets/apply.sh +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/rulesets/develop.json +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/rulesets/main.json +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/rulesets/tags.json +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.github/workflows/ruff.yml +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.gitignore +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.pre-commit-config.yaml +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.python-version +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.ruff.toml +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/.zenodo.json +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/CLAUDE.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/LICENSE +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/README.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/README.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/cache.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/console.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/core.annotation.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/core.creator.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/core.miriam.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/core.xref.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/index.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/log.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/omex.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/ontologies.term.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/webservices.chebi.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/webservices.ols.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/webservices.registry.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/webservices.unichem.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/api/webservices.webservice.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/development.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/HARMONY2026_slides.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/favicon/about.txt +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/favicon/android-chrome-192x192.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/favicon/android-chrome-512x512.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/favicon/apple-touch-icon.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/favicon/favicon-16x16.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/favicon/favicon-32x32.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/favicon/favicon.ico +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/favicon/favicon_io.zip +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/favicon/pymetadata-100x100-300dpi.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/images/favicon/site.webmanifest +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/index.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/installation.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/omex.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/docs/robots.txt +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/annotation.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/cache_path.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/MODEL2402290004.4_pymetadata.omex +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/create_omex.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/BioModelsMetadata_MODEL2402290004.csv +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/EndoAcuteBZ1.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/EndoAcuteBZ2.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/EndoAcuteBZ3.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/EndoChronicBZ.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/EndoChronicRZ1.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/EndoChronicRZ2.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/EndoNZ.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/POM253.mat +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/PlotAPCaTTaAcuteAndChronic.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/Zhou2024_Updated-model.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/getCurrentsStructureCaMKSKJrelpKinetics.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/getStartingState.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/main.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/manifest.xml +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/metadata.rdf +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/modelRunnerCaMKSKJrelpKinetics1ms.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/model_ToRORd_LandCaMKSKJrelpKinetics.m +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/omex.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/omex_from_url.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/test.omex +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/pbpko.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/examples/sbo.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/.gitignore +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/README.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/_extensions/grantmcdermott/clean/_extension.yml +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/_extensions/grantmcdermott/clean/clean.scss +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/_extensions/grantmcdermott/clean/mathjax-config.js +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/custom.scss +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/images/annotation_example.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/images/annotation_resolved.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/images/annotation_resolved_small.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/images/github_screenshot.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/images/headshot.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/images/omex_logo.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/images/omex_overview.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/images/pymetadata.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/images/pymetadata_large.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/images/qr_livermetabolism.png +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/mathjax-config.js +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/pymetadata.bib +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/pymetadata.qmd +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/presentations/HARMONY2026/styles.css +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/pyproject.toml +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.10.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.11.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.12.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.13.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.14.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.15.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.16.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.17.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.18.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.19.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.2.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.20.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.21.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.22.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.3.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.4.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.5.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.6.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.7.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.8.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.0.9.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.1.0.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.2.1.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.2.10.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.2.2.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.2.3.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.2.4.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.2.5.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.2.6.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.2.7.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.2.8.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.2.9.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.0.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.1.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.10.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.11.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.2.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.3.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.4.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.5.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.6.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.7.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.8.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.3.9.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.4.0.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.4.1.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.4.2.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.4.3.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.4.4.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.0.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.1.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.10.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.11.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.12.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.2.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.3.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.4.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.5.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.6.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.7.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.8.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.5.9.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.6.0.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.6.1.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.6.2.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/release-notes/0.6.3.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/scripts/llms_txt.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/cache.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/console.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/core/__init__.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/core/creator.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/core/miriam.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/core/synonym.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/core/xref.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/log.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/ontologies/__init__.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/ontologies/_ontology_builder.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/ontologies/kisao.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/ontologies/pbpko.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/ontologies/sbo.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/ontologies/term.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/py.typed +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/resources/ontologies/README.md +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/webservices/__init__.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/webservices/chebi.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/webservices/ols.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/webservices/registry.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/webservices/unichem.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/src/pymetadata/webservices/webservice.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/core/test_creator.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/data/omex/BIOMD0000000001.omex +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/data/omex/CombineArchiveShowCase.omex +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/data/omex/CombineArchiveShowCase_manifest.xml +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/data/omex/CompModels.omex +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/data/omex/CompModels_manifest.xml +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/data/omex/iCGB21FR.omex +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_cache.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_chebi.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_log.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_offline.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_ols.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_ontology.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_registry.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_sbo_kisao.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_unichem.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tests/test_webservice.py +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/tox.ini +0 -0
- {pymetadata-0.6.3 → pymetadata-0.6.4}/zensical.toml +0 -0
|
@@ -52,7 +52,7 @@ jobs:
|
|
|
52
52
|
persist-credentials: false
|
|
53
53
|
- name: Install uv and set the python version
|
|
54
54
|
# astral-sh/setup-uv publishes no floating major tag beyond v7
|
|
55
|
-
uses: astral-sh/setup-uv@v10.0
|
|
55
|
+
uses: astral-sh/setup-uv@v10.1.0
|
|
56
56
|
with:
|
|
57
57
|
python-version: ${{ matrix.python-version }}
|
|
58
58
|
enable-cache: true
|
|
@@ -92,7 +92,7 @@ jobs:
|
|
|
92
92
|
with:
|
|
93
93
|
persist-credentials: false
|
|
94
94
|
- name: Install uv
|
|
95
|
-
uses: astral-sh/setup-uv@v10.0
|
|
95
|
+
uses: astral-sh/setup-uv@v10.1.0
|
|
96
96
|
with:
|
|
97
97
|
python-version: "3.14"
|
|
98
98
|
enable-cache: true
|
|
@@ -8,7 +8,7 @@ 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.6.
|
|
11
|
+
version: "0.6.4"
|
|
12
12
|
date-released: "2026-09-07"
|
|
13
13
|
doi: "10.5281/zenodo.5308801"
|
|
14
14
|
license: MIT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pymetadata
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.4
|
|
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
|
|
@@ -51,6 +51,14 @@ RDFAnnotation(qualifier=BQB.IS, resource="https://en.wikipedia.org/wiki/Cytosol"
|
|
|
51
51
|
|
|
52
52
|
`resource_normalized` returns `https://identifiers.org/<prefix>:<accession>`. For namespaces which embed their prefix in the identifier (GO, CHEBI, SBO, BTO) the prefix is already part of the term and is not added a second time.
|
|
53
53
|
|
|
54
|
+
The normalization never changes what a resource says: `resource_normalized` is a URL, and parsing it again gives the same `collection` and `term`. A collection which is not in the identifiers.org registry, or a term which does not carry the prefix of its collection, cannot be written as a compact identifier and is returned as `https://identifiers.org/<collection>/<term>`:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
annotation = RDFAnnotation(qualifier=BQB.IS, resource="urn:miriam:sabiork:1406")
|
|
58
|
+
print(annotation.resource_normalized)
|
|
59
|
+
# https://identifiers.org/sabiork/1406
|
|
60
|
+
```
|
|
61
|
+
|
|
54
62
|
## Validation
|
|
55
63
|
|
|
56
64
|
Validation answers two questions: is the qualifier a real MIRIAM qualifier, and does the term match the pattern the identifiers.org registry defines for its collection?
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Release notes for pymetadata 0.6.4
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
We are pleased to release the next version of pymetadata including the
|
|
5
|
+
following changes:
|
|
6
|
+
|
|
7
|
+
## Fixes
|
|
8
|
+
- `Omex.from_directory`, and with it `Omex.from_omex` and `Omex.from_url`, add the entries in the order of the manifest, followed by the files which the manifest does not list, sorted by their location. The entries were added in the order of `os.walk`, which is the order of the file system, so `manifest.entries` and `entries_by_format` of the same archive differed between machines
|
|
9
|
+
- `RDFAnnotation.resource_normalized` keeps the collection and the term of every resource: the result is a URL, and parsing it again gives the same `collection` and `term`. A collection which is not in the identifiers.org registry (`http://identifiers.org/sabiork/1406`, `urn:miriam:foo:bar`) was reduced to the bare term, and a term which does not match the pattern of its collection (`http://identifiers.org/chebi/000000035`) lost its collection. Both are now returned as `https://identifiers.org/<collection>/<term>`, and the compact identifier of a prefix which is not in the registry stays the URL `https://identifiers.org/CMO:0000012` (#81)
|
|
10
|
+
- identifiers.org URLs of a prefix with a hyphen or an underscore, like `ec-code`, `pdb-ccd` or `go_ref`, are parsed into collection and term instead of being kept as an arbitrary URL (#81)
|
|
11
|
+
- the collection of a MIRIAM URN and of the `collection/term` notation is lowercased, as it already was for URLs, so `TAXONOMY/9606` is the collection `taxonomy` (#81)
|
|
12
|
+
|
|
13
|
+
Your pymetadata team
|
|
@@ -48,11 +48,13 @@ def get_ols_query() -> OLSQuery:
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
IDENTIFIERS_ORG_PREFIX: Final = "https://identifiers.org"
|
|
51
|
+
# prefixes of the registry consist of letters, digits, `.`, `_` and `-`,
|
|
52
|
+
# e.g., `ec-code` or `go_ref`
|
|
51
53
|
IDENTIFIERS_ORG_PATTERN_COMPACT: Final = re.compile(
|
|
52
|
-
r"^https?://identifiers.org/([a-zA-Z0-9.]+):(.+)"
|
|
54
|
+
r"^https?://identifiers.org/([a-zA-Z0-9._-]+):(.+)"
|
|
53
55
|
)
|
|
54
56
|
IDENTIFIERS_ORG_PATTERN_CLASSIC: Final = re.compile(
|
|
55
|
-
r"^https?://identifiers.org/([a-zA-Z0-9.]+)/(.+)"
|
|
57
|
+
r"^https?://identifiers.org/([a-zA-Z0-9._-]+)/(.+)"
|
|
56
58
|
)
|
|
57
59
|
|
|
58
60
|
BIOREGISTRY_PREFIX: Final = "https://bioregistry.io"
|
|
@@ -167,21 +169,15 @@ class RDFAnnotation:
|
|
|
167
169
|
match3 = MIRIAM_URN_PATTERN.match(resource)
|
|
168
170
|
if match3:
|
|
169
171
|
tokens = match3.group(1).split(":")
|
|
170
|
-
self.collection = tokens[0]
|
|
172
|
+
self.collection = tokens[0].lower()
|
|
171
173
|
self.term = ":".join(tokens[1:]).replace("%3A", ":")
|
|
172
174
|
self.provider = ProviderType.IDENTIFIERS_ORG
|
|
173
175
|
|
|
174
|
-
logger.warning(
|
|
175
|
-
"Deprecated urn pattern `%s` updated: %s",
|
|
176
|
-
resource,
|
|
177
|
-
self.resource_normalized,
|
|
178
|
-
)
|
|
179
|
-
|
|
180
176
|
else:
|
|
181
177
|
# handle short notation
|
|
182
178
|
tokens = resource.split("/")
|
|
183
179
|
if len(tokens) > 1:
|
|
184
|
-
self.collection = tokens[0]
|
|
180
|
+
self.collection = tokens[0].lower()
|
|
185
181
|
self.term = "/".join(tokens[1:])
|
|
186
182
|
self.provider = ProviderType.IDENTIFIERS_ORG
|
|
187
183
|
elif len(tokens) == 1 and ":" in tokens[0]:
|
|
@@ -209,6 +205,13 @@ class RDFAnnotation:
|
|
|
209
205
|
if self.collection in self.replaced_collections:
|
|
210
206
|
self.collection = self.replaced_collections[self.collection]
|
|
211
207
|
|
|
208
|
+
if resource.startswith("urn:miriam:"):
|
|
209
|
+
logger.warning(
|
|
210
|
+
"Deprecated urn pattern `%s` updated: %s",
|
|
211
|
+
resource,
|
|
212
|
+
self.resource_normalized,
|
|
213
|
+
)
|
|
214
|
+
|
|
212
215
|
if validate:
|
|
213
216
|
self.validate()
|
|
214
217
|
|
|
@@ -244,21 +247,33 @@ class RDFAnnotation:
|
|
|
244
247
|
`https://identifiers.org/<prefix>:<accession>`. If the namespace is
|
|
245
248
|
embedded in the LUI the prefix is already part of the term, otherwise
|
|
246
249
|
the prefix of the identifiers.org registry is prepended.
|
|
250
|
+
|
|
251
|
+
The normalization never changes what the resource says: the result is
|
|
252
|
+
an url, and parsing it again yields the same `collection` and `term`.
|
|
253
|
+
A collection which is not in the registry, or a term which does not
|
|
254
|
+
carry the prefix of its collection, can not be written as a compact
|
|
255
|
+
identifier and is returned as
|
|
256
|
+
`https://identifiers.org/<collection>/<term>`. Whether the term is
|
|
257
|
+
valid does not matter here, this is the task of `validate`.
|
|
258
|
+
|
|
259
|
+
Resources without a collection, i.e., arbitrary urls, are returned
|
|
260
|
+
unchanged.
|
|
247
261
|
"""
|
|
248
262
|
if not self.term:
|
|
249
263
|
return None
|
|
250
264
|
|
|
251
|
-
if
|
|
252
|
-
self.
|
|
253
|
-
|
|
254
|
-
)
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
265
|
+
if self.provider != ProviderType.IDENTIFIERS_ORG or self.collection is None:
|
|
266
|
+
return self.term
|
|
267
|
+
|
|
268
|
+
namespace = get_registry().ns_dict.get(self.collection, None)
|
|
269
|
+
if namespace and not namespace.namespaceEmbeddedInLui:
|
|
270
|
+
return f"{IDENTIFIERS_ORG_PREFIX}/{self.collection}:{self.term}"
|
|
271
|
+
|
|
272
|
+
# the term is only a compact identifier if its prefix is the collection
|
|
273
|
+
if self.term.lower().startswith(f"{self.collection}:"):
|
|
274
|
+
return f"{IDENTIFIERS_ORG_PREFIX}/{self.term}"
|
|
260
275
|
|
|
261
|
-
return self.term
|
|
276
|
+
return f"{IDENTIFIERS_ORG_PREFIX}/{self.collection}/{self.term}"
|
|
262
277
|
|
|
263
278
|
def __repr__(self) -> str:
|
|
264
279
|
"""Get representation string."""
|
|
@@ -743,6 +743,10 @@ class Omex:
|
|
|
743
743
|
`Omex.guess_format`; SED-ML files added this way get `master=True`,
|
|
744
744
|
as they are the entry point of a simulation study.
|
|
745
745
|
|
|
746
|
+
The entries are in the order of the manifest, followed by the files
|
|
747
|
+
which the manifest does not list, sorted by their location. The order
|
|
748
|
+
does not depend on the file system.
|
|
749
|
+
|
|
746
750
|
Args:
|
|
747
751
|
directory: directory with the content of the archive
|
|
748
752
|
|
|
@@ -785,7 +789,8 @@ class Omex:
|
|
|
785
789
|
# new archive
|
|
786
790
|
omex = Omex()
|
|
787
791
|
|
|
788
|
-
#
|
|
792
|
+
# locations of all files
|
|
793
|
+
file_paths: dict[str, str] = {}
|
|
789
794
|
for root, _dirs, files in os.walk(str(directory)):
|
|
790
795
|
for file in files:
|
|
791
796
|
file_path = os.path.join(root, file)
|
|
@@ -795,32 +800,46 @@ class Omex:
|
|
|
795
800
|
if location == "./manifest.xml":
|
|
796
801
|
# manifest is created from the internal manifest entries
|
|
797
802
|
continue
|
|
803
|
+
file_paths[location] = file_path
|
|
804
|
+
|
|
805
|
+
# The order of `os.walk` is the order of the file system, which differs
|
|
806
|
+
# between machines: the entries are added in the order of the manifest,
|
|
807
|
+
# followed by the files which the manifest does not list, by location.
|
|
808
|
+
positions: dict[str, int] = {}
|
|
809
|
+
if manifest:
|
|
810
|
+
positions = {e.location: k for k, e in enumerate(manifest.entries)}
|
|
811
|
+
locations = sorted(
|
|
812
|
+
file_paths, key=lambda loc: (positions.get(loc, len(positions)), loc)
|
|
813
|
+
)
|
|
798
814
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
master = False
|
|
813
|
-
if format and ManifestEntry.is_format(
|
|
814
|
-
format_key="sedml", format=format
|
|
815
|
-
):
|
|
816
|
-
master = True
|
|
817
|
-
entry = ManifestEntry(
|
|
818
|
-
location=location,
|
|
819
|
-
format=format,
|
|
820
|
-
master=master,
|
|
815
|
+
# iterate over all locations and add entry
|
|
816
|
+
for location in locations:
|
|
817
|
+
file_path = file_paths[location]
|
|
818
|
+
logger.debug("'%s' -> '%s'", file_path, location)
|
|
819
|
+
entry: ManifestEntry
|
|
820
|
+
if manifest and location in manifest:
|
|
821
|
+
# use entry from existing manifest
|
|
822
|
+
entry = manifest[location]
|
|
823
|
+
else:
|
|
824
|
+
if manifest and location not in manifest:
|
|
825
|
+
logger.warning(
|
|
826
|
+
"Entry with location missing in manifest.xml: '%s'",
|
|
827
|
+
location,
|
|
821
828
|
)
|
|
822
829
|
|
|
823
|
-
|
|
830
|
+
format = Omex.guess_format(Path(file_path))
|
|
831
|
+
master = False
|
|
832
|
+
if format and ManifestEntry.is_format(
|
|
833
|
+
format_key="sedml", format=format
|
|
834
|
+
):
|
|
835
|
+
master = True
|
|
836
|
+
entry = ManifestEntry(
|
|
837
|
+
location=location,
|
|
838
|
+
format=format,
|
|
839
|
+
master=master,
|
|
840
|
+
)
|
|
841
|
+
|
|
842
|
+
omex.add_entry(entry_path=Path(file_path), entry=entry)
|
|
824
843
|
|
|
825
844
|
return omex
|
|
826
845
|
|
|
@@ -227,3 +227,82 @@ def test_resource_normalized(resource: str, expected: str) -> None:
|
|
|
227
227
|
"""Test normalization to identifiers.org compact identifiers."""
|
|
228
228
|
a = RDFAnnotation(qualifier=BQB.IS, resource=resource)
|
|
229
229
|
assert a.resource_normalized == expected
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
resource_kept_data = [
|
|
233
|
+
# collection which is not in the registry (see #81)
|
|
234
|
+
("http://identifiers.org/sabiork/1406", "https://identifiers.org/sabiork/1406"),
|
|
235
|
+
("urn:miriam:foo:bar", "https://identifiers.org/foo/bar"),
|
|
236
|
+
("foo/bar", "https://identifiers.org/foo/bar"),
|
|
237
|
+
# collection which is not in the registry, term with a prefix of its own
|
|
238
|
+
(
|
|
239
|
+
"http://identifiers.org/unit/UO:0000040",
|
|
240
|
+
"https://identifiers.org/unit/UO:0000040",
|
|
241
|
+
),
|
|
242
|
+
# compact identifier of a prefix which is not in the registry
|
|
243
|
+
("https://identifiers.org/CMO:0000012", "https://identifiers.org/CMO:0000012"),
|
|
244
|
+
("CMO:0000012", "https://identifiers.org/CMO:0000012"),
|
|
245
|
+
# term which does not match the pattern of its collection
|
|
246
|
+
(
|
|
247
|
+
"http://identifiers.org/chebi/000000035",
|
|
248
|
+
"https://identifiers.org/chebi/000000035",
|
|
249
|
+
),
|
|
250
|
+
("taxonomy/abc", "https://identifiers.org/taxonomy:abc"),
|
|
251
|
+
# prefix with a hyphen or an underscore
|
|
252
|
+
("urn:miriam:ec-code:1.1.1.1", "https://identifiers.org/ec-code:1.1.1.1"),
|
|
253
|
+
(
|
|
254
|
+
"https://identifiers.org/ec-code/1.1.1.1",
|
|
255
|
+
"https://identifiers.org/ec-code:1.1.1.1",
|
|
256
|
+
),
|
|
257
|
+
("go_ref/GO_REF:0000041", "https://identifiers.org/GO_REF:0000041"),
|
|
258
|
+
(
|
|
259
|
+
"https://identifiers.org/GO_REF:0000041",
|
|
260
|
+
"https://identifiers.org/GO_REF:0000041",
|
|
261
|
+
),
|
|
262
|
+
# prefixes are case insensitive
|
|
263
|
+
("urn:miriam:CHEBI:CHEBI%3A33699", "https://identifiers.org/CHEBI:33699"),
|
|
264
|
+
("TAXONOMY/9606", "https://identifiers.org/taxonomy:9606"),
|
|
265
|
+
]
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def assert_resource_kept(resource: str) -> None:
|
|
269
|
+
"""Assert that the normalized resource is a url with the same meaning."""
|
|
270
|
+
a = RDFAnnotation(qualifier=BQB.IS, resource=resource, validate=False)
|
|
271
|
+
normalized = a.resource_normalized
|
|
272
|
+
assert normalized
|
|
273
|
+
assert normalized.startswith("https://")
|
|
274
|
+
|
|
275
|
+
b = RDFAnnotation(qualifier=BQB.IS, resource=normalized, validate=False)
|
|
276
|
+
assert (b.collection, b.term) == (a.collection, a.term)
|
|
277
|
+
assert b.resource_normalized == normalized
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@pytest.mark.parametrize("resource,expected", resource_kept_data)
|
|
281
|
+
def test_resource_normalized_keeps_resource(resource: str, expected: str) -> None:
|
|
282
|
+
"""Test that collection and term survive the normalization, see #81."""
|
|
283
|
+
a = RDFAnnotation(qualifier=BQB.IS, resource=resource, validate=False)
|
|
284
|
+
assert a.resource_normalized == expected
|
|
285
|
+
assert_resource_kept(resource)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
@pytest.mark.parametrize(
|
|
289
|
+
"resource", [resource for resource, _ in resource_normalized_data]
|
|
290
|
+
)
|
|
291
|
+
def test_resource_normalized_roundtrip(resource: str) -> None:
|
|
292
|
+
"""Test that the normalized resource parses to the same annotation."""
|
|
293
|
+
assert_resource_kept(resource)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def test_resource_normalized_registry() -> None:
|
|
297
|
+
"""Test the normalization with the sample of every registry namespace."""
|
|
298
|
+
from pymetadata.webservices.registry import get_registry
|
|
299
|
+
|
|
300
|
+
for prefix, namespace in get_registry().ns_dict.items():
|
|
301
|
+
sample_id = namespace.sampleId
|
|
302
|
+
if not sample_id:
|
|
303
|
+
continue
|
|
304
|
+
for resource in [
|
|
305
|
+
f"https://identifiers.org/{prefix}/{sample_id}",
|
|
306
|
+
f"urn:miriam:{prefix}:{sample_id.replace(':', '%3A')}",
|
|
307
|
+
]:
|
|
308
|
+
assert_resource_kept(resource)
|
|
@@ -272,3 +272,66 @@ def test_manifest_without_namespace(tmp_path: Path) -> None:
|
|
|
272
272
|
manifest = Manifest.from_manifest(manifest_path)
|
|
273
273
|
assert len(manifest) == 2
|
|
274
274
|
assert manifest["./model.xml"].master is True
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
# locations of a manifest in an order which is neither sorted nor the order in
|
|
278
|
+
# which the files are created, so that no file system returns it by chance
|
|
279
|
+
ORDERED_LOCATIONS = [
|
|
280
|
+
f"./{directory}{name}.xml"
|
|
281
|
+
for name in ["m", "b", "z", "a", "q", "c", "y", "d"]
|
|
282
|
+
for directory in ["models/", "", "data/"]
|
|
283
|
+
]
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def _ordered_directory(directory: Path, locations: list[str]) -> Path:
|
|
287
|
+
"""Write the files of all locations and a manifest which lists `locations`."""
|
|
288
|
+
for location in sorted(ORDERED_LOCATIONS):
|
|
289
|
+
path = directory / location
|
|
290
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
291
|
+
path.write_text("<sbml/>")
|
|
292
|
+
|
|
293
|
+
manifest = Manifest()
|
|
294
|
+
for location in locations:
|
|
295
|
+
manifest.add_entry(ManifestEntry(location=location, format="sbml"))
|
|
296
|
+
manifest.to_manifest(directory / "manifest.xml")
|
|
297
|
+
return directory
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def test_from_directory_keeps_manifest_order(tmp_path: Path) -> None:
|
|
301
|
+
"""The entries of a directory are in the order of its manifest.
|
|
302
|
+
|
|
303
|
+
The order in which the file system returns the files differs between
|
|
304
|
+
machines and must not be the order of the entries.
|
|
305
|
+
"""
|
|
306
|
+
directory = _ordered_directory(tmp_path, ORDERED_LOCATIONS)
|
|
307
|
+
omex = Omex.from_directory(directory)
|
|
308
|
+
locations = [entry.location for entry in omex.manifest.entries]
|
|
309
|
+
assert locations == [".", "./manifest.xml", *ORDERED_LOCATIONS]
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def test_from_directory_appends_unlisted_files(tmp_path: Path) -> None:
|
|
313
|
+
"""Files which the manifest does not list follow the listed ones, sorted."""
|
|
314
|
+
listed = ORDERED_LOCATIONS[:5]
|
|
315
|
+
directory = _ordered_directory(tmp_path, listed)
|
|
316
|
+
omex = Omex.from_directory(directory)
|
|
317
|
+
locations = [entry.location for entry in omex.manifest.entries]
|
|
318
|
+
unlisted = sorted(set(ORDERED_LOCATIONS) - set(listed))
|
|
319
|
+
assert locations == [".", "./manifest.xml", *listed, *unlisted]
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def test_from_directory_without_manifest_is_sorted(tmp_path: Path) -> None:
|
|
323
|
+
"""Without a manifest the entries are sorted by their location."""
|
|
324
|
+
directory = _ordered_directory(tmp_path, [])
|
|
325
|
+
(directory / "manifest.xml").unlink()
|
|
326
|
+
omex = Omex.from_directory(directory)
|
|
327
|
+
locations = [entry.location for entry in omex.manifest.entries]
|
|
328
|
+
assert locations == [".", "./manifest.xml", *sorted(ORDERED_LOCATIONS)]
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def test_omex_roundtrip_keeps_manifest_order(tmp_path: Path) -> None:
|
|
332
|
+
"""The order of the entries survives writing and reading an archive."""
|
|
333
|
+
omex = Omex.from_directory(_ordered_directory(tmp_path / "in", ORDERED_LOCATIONS))
|
|
334
|
+
omex_path = tmp_path / "ordered.omex"
|
|
335
|
+
omex.to_omex(omex_path)
|
|
336
|
+
locations = [entry.location for entry in Omex.from_omex(omex_path).manifest.entries]
|
|
337
|
+
assert locations == [".", "./manifest.xml", *ORDERED_LOCATIONS]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/MODEL2402290004.4_pymetadata.omex
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pymetadata-0.6.3 → pymetadata-0.6.4}/examples/omex/biomodels_omex/files/Zhou2024_Updated-model.m
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|