indicium-adapters 0.6.0__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.
- indicium_adapters-0.6.0/.github/workflows/ci.yml +32 -0
- indicium_adapters-0.6.0/.github/workflows/release.yml +97 -0
- indicium_adapters-0.6.0/.gitignore +12 -0
- indicium_adapters-0.6.0/CHANGELOG.md +292 -0
- indicium_adapters-0.6.0/CITATION.cff +25 -0
- indicium_adapters-0.6.0/CONTRIBUTING.md +39 -0
- indicium_adapters-0.6.0/LICENSE +21 -0
- indicium_adapters-0.6.0/PKG-INFO +311 -0
- indicium_adapters-0.6.0/README.md +256 -0
- indicium_adapters-0.6.0/RELEASING.md +190 -0
- indicium_adapters-0.6.0/SECURITY.md +14 -0
- indicium_adapters-0.6.0/docs/assets/brand/indicium-mark-dark.svg +12 -0
- indicium_adapters-0.6.0/docs/assets/brand/indicium-mark.svg +12 -0
- indicium_adapters-0.6.0/pyproject.toml +70 -0
- indicium_adapters-0.6.0/scripts/check_release.py +55 -0
- indicium_adapters-0.6.0/src/indicium_adapters/__init__.py +281 -0
- indicium_adapters-0.6.0/src/indicium_adapters/asb/__init__.py +57 -0
- indicium_adapters-0.6.0/src/indicium_adapters/asb/adapter.py +170 -0
- indicium_adapters-0.6.0/src/indicium_adapters/asb/biotools.py +101 -0
- indicium_adapters-0.6.0/src/indicium_adapters/asb/cli.py +166 -0
- indicium_adapters-0.6.0/src/indicium_adapters/asb/loader.py +273 -0
- indicium_adapters-0.6.0/src/indicium_adapters/asb/mapper.py +259 -0
- indicium_adapters-0.6.0/src/indicium_adapters/asb/models.py +169 -0
- indicium_adapters-0.6.0/src/indicium_adapters/asb/prov.py +66 -0
- indicium_adapters-0.6.0/src/indicium_adapters/asb/round_trip.py +159 -0
- indicium_adapters-0.6.0/src/indicium_adapters/composite.py +99 -0
- indicium_adapters-0.6.0/tests/__init__.py +0 -0
- indicium_adapters-0.6.0/tests/asb/__init__.py +0 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/indicium_graph.ttl +15 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/indicium_graph_broken.ttl +5 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/sample_collection/claims.yaml +15 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/sample_collection/collection.yaml +10 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/sample_collection/skills/feature-detection-lcms/SKILL.md +24 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/sample_collection/tools/mzmine.yaml +13 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/skipped_skill_collection/collection.yaml +9 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/skipped_skill_collection/leaves/skill-with-claim-and-empty-span/SKILL.md +12 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/slug_list_collection/collection.yaml +19 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/slug_list_collection/leaves/skill-with-claim/SKILL.md +28 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/slug_list_collection/leaves/skill-with-provenance-papers/SKILL.md +24 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/slug_list_collection/skills/router/SKILL.md +6 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/slug_list_collection/tools/pathway-tool.yaml +6 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/slug_list_collection/tools/plain-tool.yaml +9 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/unlisted_claims_collection/collection.yaml +7 -0
- indicium_adapters-0.6.0/tests/asb/fixtures/unlisted_claims_collection/leaves/skill-declaring-claims/SKILL.md +8 -0
- indicium_adapters-0.6.0/tests/asb/test_adapter.py +147 -0
- indicium_adapters-0.6.0/tests/asb/test_biotools.py +69 -0
- indicium_adapters-0.6.0/tests/asb/test_cli.py +191 -0
- indicium_adapters-0.6.0/tests/asb/test_cli_optional_dependencies.py +34 -0
- indicium_adapters-0.6.0/tests/asb/test_loader.py +138 -0
- indicium_adapters-0.6.0/tests/asb/test_mapper.py +313 -0
- indicium_adapters-0.6.0/tests/asb/test_models.py +69 -0
- indicium_adapters-0.6.0/tests/asb/test_package.py +8 -0
- indicium_adapters-0.6.0/tests/asb/test_prov.py +35 -0
- indicium_adapters-0.6.0/tests/asb/test_round_trip.py +170 -0
- indicium_adapters-0.6.0/tests/test_classification_vocabulary.py +183 -0
- indicium_adapters-0.6.0/tests/test_composite.py +291 -0
- indicium_adapters-0.6.0/tests/test_protocol.py +263 -0
- indicium_adapters-0.6.0/tests/test_release_metadata.py +126 -0
- indicium_adapters-0.6.0/uv.lock +708 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python-version }}
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
# indicium-standard resolves from PyPI (2.0.0 and later).
|
|
25
|
+
# .[asb] brings httpx + pydantic + pyyaml for the src/indicium_adapters/asb
|
|
26
|
+
# submodule that tests/asb exercises; .[dev] brings pytest, pytest-cov,
|
|
27
|
+
# pyshacl and the pinned ruff.
|
|
28
|
+
pip install -e ".[dev,asb]"
|
|
29
|
+
- name: Lint
|
|
30
|
+
run: ruff check .
|
|
31
|
+
- name: Run tests
|
|
32
|
+
run: pytest --cov=indicium_adapters --cov-report=term-missing
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v7
|
|
16
|
+
|
|
17
|
+
- uses: astral-sh/setup-uv@v7
|
|
18
|
+
|
|
19
|
+
- name: Check tag, version and release date
|
|
20
|
+
run: uv run --no-project --python 3.12 python scripts/check_release.py --tag "$GITHUB_REF_NAME" --notes-output "$RUNNER_TEMP/release-notes.md"
|
|
21
|
+
|
|
22
|
+
- name: Require indicium-standard on PyPI
|
|
23
|
+
run: |
|
|
24
|
+
curl -sSf -o /dev/null https://pypi.org/pypi/indicium-standard/2.0.0/json || {
|
|
25
|
+
echo "::error::indicium-standard 2.0.0 is not on PyPI yet; release after it"
|
|
26
|
+
exit 1
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
- name: Install, lint and test
|
|
30
|
+
run: |
|
|
31
|
+
uv venv --python 3.12 .venv
|
|
32
|
+
uv pip install --python .venv/bin/python --no-sources -e ".[dev,asb]"
|
|
33
|
+
.venv/bin/ruff check .
|
|
34
|
+
.venv/bin/pytest
|
|
35
|
+
|
|
36
|
+
- name: Build and check distributions
|
|
37
|
+
run: |
|
|
38
|
+
rm -rf dist
|
|
39
|
+
uv build --no-sources
|
|
40
|
+
uvx --from twine==7.0.0 twine check --strict dist/*
|
|
41
|
+
|
|
42
|
+
- name: Check installed wheel
|
|
43
|
+
run: |
|
|
44
|
+
uv venv --python 3.11 .wheel-env
|
|
45
|
+
uv pip install --python .wheel-env/bin/python --no-sources dist/*.whl
|
|
46
|
+
uv pip check --python .wheel-env/bin/python
|
|
47
|
+
.wheel-env/bin/python -c "import sys, indicium, indicium_adapters; from importlib.metadata import version; v = version('indicium-adapters'); assert 'v' + v == sys.argv[1], v; print('indicium-adapters', v, 'indicium-standard', version('indicium-standard'))" "$GITHUB_REF_NAME"
|
|
48
|
+
|
|
49
|
+
- uses: actions/upload-artifact@v7
|
|
50
|
+
with:
|
|
51
|
+
name: release-distributions
|
|
52
|
+
path: dist/*
|
|
53
|
+
if-no-files-found: error
|
|
54
|
+
|
|
55
|
+
- uses: actions/upload-artifact@v7
|
|
56
|
+
with:
|
|
57
|
+
name: release-notes
|
|
58
|
+
path: ${{ runner.temp }}/release-notes.md
|
|
59
|
+
if-no-files-found: error
|
|
60
|
+
|
|
61
|
+
publish:
|
|
62
|
+
needs: build
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
environment:
|
|
65
|
+
name: pypi
|
|
66
|
+
url: https://pypi.org/p/indicium-adapters
|
|
67
|
+
permissions:
|
|
68
|
+
id-token: write
|
|
69
|
+
steps:
|
|
70
|
+
- uses: actions/download-artifact@v8
|
|
71
|
+
with:
|
|
72
|
+
name: release-distributions
|
|
73
|
+
path: dist
|
|
74
|
+
|
|
75
|
+
- name: Publish to PyPI with Trusted Publishing
|
|
76
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
77
|
+
|
|
78
|
+
github-release:
|
|
79
|
+
needs: publish
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
permissions:
|
|
82
|
+
contents: write
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/download-artifact@v8
|
|
85
|
+
with:
|
|
86
|
+
name: release-distributions
|
|
87
|
+
path: dist
|
|
88
|
+
|
|
89
|
+
- uses: actions/download-artifact@v8
|
|
90
|
+
with:
|
|
91
|
+
name: release-notes
|
|
92
|
+
path: release-notes
|
|
93
|
+
|
|
94
|
+
- uses: softprops/action-gh-release@v3
|
|
95
|
+
with:
|
|
96
|
+
body_path: release-notes/release-notes.md
|
|
97
|
+
files: dist/*
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [0.6.0] - 2026-11-02
|
|
11
|
+
|
|
12
|
+
First release published to PyPI. 0.5.0 was never tagged or published, and its
|
|
13
|
+
changes ship in this release; the tag before this one is `v0.4.0`.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- `ClassificationVocabularyProvider`, an opt-in protocol for an adapter that
|
|
17
|
+
declares curated classification vocabulary: `primary_domain`, `subdomains` and
|
|
18
|
+
`techniques`. `classification_vocabulary(adapter)` reads the three members into a
|
|
19
|
+
`ClassificationVocabulary` and never substitutes `domain_id` for a missing
|
|
20
|
+
`primary_domain`; an adapter that declares nothing reports `primary_domain=None`.
|
|
21
|
+
(#5)
|
|
22
|
+
- Convention: `DomainAdapter.enrich_claim()` MAY set an
|
|
23
|
+
`ontology_term_justifications: dict[str, str]` companion map alongside
|
|
24
|
+
`ontology_terms`, mapping the same slot keys to SEMAPV justification CURIEs (e.g.
|
|
25
|
+
`semapv:CompositeMatching`, `semapv:LexicalMatching`). Downstream SSSOM emitters
|
|
26
|
+
(Perspicacité) use this as `mapping_justification`; absent keys default to
|
|
27
|
+
`semapv:CompositeMatching`. Documented in the `enrich_claim` docstring and the
|
|
28
|
+
README.
|
|
29
|
+
- `RoundTripResult.skills_checked`, also printed by `verify-claims` and returned
|
|
30
|
+
under `skills_checked` in its JSON: the number of skills read from disk, so a pass
|
|
31
|
+
that read no skill is visible.
|
|
32
|
+
- `RoundTripResult.skills_listed` and `skills_skipped`, also in the `verify-claims`
|
|
33
|
+
JSON and pretty output: the entries under `skills` in `collection.yaml`, and the
|
|
34
|
+
slug and reason of each listed skill that has no SKILL.md or fails validation.
|
|
35
|
+
The loader keeps such skills in `ASBCollection.skipped_skills` (new model
|
|
36
|
+
`ASBSkippedSkill`) instead of dropping them.
|
|
37
|
+
- `ASBClaimRecord.context`, the SuperPattern context slot. The mapper writes it as
|
|
38
|
+
`asb:context`, which the indicium `asb:Claim` shape requires, when the record has
|
|
39
|
+
one. An earlier entry and the body of commit 8ebaff0 said ASB claim records carry
|
|
40
|
+
no context; ASB's own claims do, and it was this package's record that lacked the
|
|
41
|
+
field.
|
|
42
|
+
- `RoundTripResult.skills_with_unlisted_claims`: skills whose frontmatter declares
|
|
43
|
+
`n_claims` above 0 but lists no claim IRI. `verify-claims` returns it in its JSON
|
|
44
|
+
and prints a warning on stderr; it does not fail the gate. `ASBSkillRecord` reads
|
|
45
|
+
`n_claims`.
|
|
46
|
+
- **The round-trip gate fails on a graph that indicium's shapes would not check.**
|
|
47
|
+
`run_round_trip_check()` and `verify-claims` now fail (exit 1) when no node of the
|
|
48
|
+
indicium graph is typed with a class an indicium SHACL shape targets: validating
|
|
49
|
+
such a graph has no focus node and conforms whatever it holds. The count is
|
|
50
|
+
`RoundTripResult.shape_targeted_nodes`, returned as `shape_targeted_nodes` in the
|
|
51
|
+
`verify-claims` JSON. `shape_targeted_classes()` reads the targets from the shape
|
|
52
|
+
files indicium ships, and `count_shape_targeted_nodes()` counts a graph's nodes.
|
|
53
|
+
- `tests/test_release_metadata.py`: `CITATION.cff` and `pyproject.toml` carry the
|
|
54
|
+
same version, `indicium_adapters.asb.__version__` is the installed distribution
|
|
55
|
+
version, this file has a section for that version and at most one Unreleased
|
|
56
|
+
section, and `SECURITY.md` supports the `pyproject.toml` major.minor line.
|
|
57
|
+
- `.github/workflows/release.yml`: on a `v*` tag, checks the tag, the versions and
|
|
58
|
+
the changelog date (`scripts/check_release.py`), runs lint and tests, builds the
|
|
59
|
+
sdist and the wheel with `uv build`, runs `twine check --strict`, installs the
|
|
60
|
+
wheel in a clean environment and imports it, publishes to PyPI with Trusted
|
|
61
|
+
Publishing from the `pypi` environment, and creates the GitHub release with the
|
|
62
|
+
two distributions. `RELEASING.md` holds the checklist.
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
- **The dependency is the renamed `indicium-standard>=2.0.0`** (was `indicium>=1.7`),
|
|
66
|
+
and the version moved to 0.6.0 in the same commit. The import name stays
|
|
67
|
+
`indicium`. The ASB mapper requires indicium main at or after 62c7f52, the first
|
|
68
|
+
commit exporting `ASB_BASE` and `INDICIUM_BASE`; earlier 2.0.0 builds satisfy the
|
|
69
|
+
floor but make `import indicium_adapters.asb` raise `ImportError`.
|
|
70
|
+
- **`requires-python` lowered from `>=3.12` to `>=3.11`.** Nothing in the package
|
|
71
|
+
needed 3.12: all 24 source and test modules parse under 3.11 (no PEP 695
|
|
72
|
+
type-parameter syntax, no `type` alias statements), there is no 3.12-only stdlib
|
|
73
|
+
API in use, and the only runtime dependency, `indicium-standard`, already declares
|
|
74
|
+
`>=3.11`. At that commit the suite passed unchanged on 3.11: 73 passed, 4 skipped,
|
|
75
|
+
90.31% coverage.
|
|
76
|
+
|
|
77
|
+
The floor mattered because it made every `DomainAdapter` uninstallable in the
|
|
78
|
+
AgenticScienceBuilder environment, which runs Python 3.11 and is where the
|
|
79
|
+
classification vocabulary adapters feed is actually consumed. With the floor
|
|
80
|
+
lowered, installing `indicium-adapters` plus `indicium-adapters-astronomy` into
|
|
81
|
+
that environment takes ASB's controlled vocabulary from 17 primary domains to 18,
|
|
82
|
+
adding `astronomy` along with its 11 subdomains and its techniques; previously an
|
|
83
|
+
astronomy paper was classified as `other` no matter what.
|
|
84
|
+
- Dropped the `Programming Language :: Python :: 3.10` classifier. It advertised a
|
|
85
|
+
version that could never resolve, since `indicium-standard` requires `>=3.11`.
|
|
86
|
+
- **The ASB mapper takes its vocabulary bases from indicium** (`ASB_BASE`,
|
|
87
|
+
`INDICIUM_BASE`) instead of the hardcoded
|
|
88
|
+
`https://w3id.org/holobiomicslab/indicium#`. A claim is typed `asb:Claim`; its
|
|
89
|
+
subject, predicate and object fill `asb:subject`, `asb:relation` and `asb:object`,
|
|
90
|
+
the terms the indicium `asb:Claim` shape declares. A qualifier rides
|
|
91
|
+
`asb:qualifier` when it is a closed Bucur term and `asb:domainQualifier`
|
|
92
|
+
otherwise, as the `DomainAdapter.qualifiers` contract states. The other mapper
|
|
93
|
+
terms keep their local names under `INDICIUM_BASE`. No file in the current
|
|
94
|
+
collections uses the old namespace, so it is not read as an alias.
|
|
95
|
+
- **Evidence spans, tools and papers are typed and described with indicium's own
|
|
96
|
+
terms, so its shapes check them.** On the metabolomics v2 collection the graph
|
|
97
|
+
typed 0 of its 22,753 typed nodes with a class an indicium shape targets, and
|
|
98
|
+
`validate_graph` conformed without checking anything. An evidence span is now an
|
|
99
|
+
Evidence, `sepio:0000002` (was `indicium:Evidence`), with `indicium:eco_code`,
|
|
100
|
+
`indicium:quote_exact`, `indicium:source_doi` and `indicium:paragraph_id`. A tool
|
|
101
|
+
is a SoftwareEntity, `fabio:ComputerProgram` (was `indicium:SoftwareEntity`), with
|
|
102
|
+
its IRI in `dct:identifier`, `indicium:canonical_url` as an IRI (a value that is
|
|
103
|
+
not an absolute IRI stays a literal, which the shape reports) and
|
|
104
|
+
`indicium:edam_operation` and `indicium:edam_topics`. A paper is a Source,
|
|
105
|
+
`fabio:Expression` (was `indicium:InformationSource`), with its DOI in
|
|
106
|
+
`dct:identifier` (was `cito:hasIdentifier`) and its title in `dct:title`. The v2
|
|
107
|
+
graph now has 16,894 nodes the shapes target, and it conforms.
|
|
108
|
+
- `ASBEvidenceSpan.eco_code` defaults to `textual_quotation`, the EcoCodeAsbSubset
|
|
109
|
+
value indicium maps to `ECO:0000033`. The former default `eco:textual-quotation`
|
|
110
|
+
was written as `ECO_textual-quotation`, an ECO IRI that does not exist. Every
|
|
111
|
+
EcoCodeAsbSubset value maps to the ECO term indicium gives it, an `ECO:` CURIE to
|
|
112
|
+
its IRI, and any other value stays a literal that the indicium shape reports.
|
|
113
|
+
- `indicium:bio_tools_id` is a string, written only when a bio.tools id is known;
|
|
114
|
+
an unresolved id is no longer written as `rdf:nil`, which the shape rejects.
|
|
115
|
+
- `ASBAdapter` writes one paper node per DOI. When the records citing a paper give
|
|
116
|
+
it different titles it gets no `dct:title`, which the indicium shape allows once,
|
|
117
|
+
and the adapter warns with their count and the first ten DOIs: 50 of the 498
|
|
118
|
+
papers of metabolomics v2.
|
|
119
|
+
- Skill and tool instance IRIs keep the `https://w3id.org/holobiomicslab/asb-skill/`
|
|
120
|
+
and `.../asb-tool/` form that ASB's release code mints, now exported as
|
|
121
|
+
`ASB_SKILL_BASE` and `ASB_TOOL_BASE`. `ASBAdapter` binds the `asb:` prefix to the
|
|
122
|
+
vocabulary and `asbskill:` to the skill instances.
|
|
123
|
+
- `ASBSourcePaper.title` may be empty: current releases leave it empty when the
|
|
124
|
+
title was not resolved, and the DOI identifies the paper. The mapper writes no
|
|
125
|
+
empty title.
|
|
126
|
+
- A skill or tool record that fails validation is skipped with a warning; the
|
|
127
|
+
loader no longer catches every exception, and `tools.lock.yaml` entries that fail
|
|
128
|
+
are no longer dropped silently.
|
|
129
|
+
- `indicium_adapters.asb.__version__` reads the installed distribution version (it
|
|
130
|
+
was a hardcoded `0.5.0`). `CITATION.cff` moves from 0.4.0 to 0.6.0, gains the
|
|
131
|
+
author's ORCID and drops the `date-released` of 0.4.0, since 0.6.0 has no release.
|
|
132
|
+
- `SECURITY.md` writes its supported-versions table in plain text and lists 0.6.x
|
|
133
|
+
as the supported line (it still listed 0.4.x).
|
|
134
|
+
- CI tests Python 3.11, 3.12 and 3.13. `ruff check .` now fails the job on any
|
|
135
|
+
finding; ruff is pinned to 0.17.3 in the `dev` extra because each release widens
|
|
136
|
+
its default rule set. The extras install no longer falls back to a bare install.
|
|
137
|
+
CI installs `indicium-standard` from the public repository, pinned to commit
|
|
138
|
+
500dd82, and no longer needs the `ORG_PAT` token; the pin moves to PyPI once
|
|
139
|
+
2.0.0 is published.
|
|
140
|
+
- `uv.lock` is refreshed: it still declared `requires-python = ">=3.12"`.
|
|
141
|
+
- `pyproject.toml` declares `readme = "README.md"`. The built wheel's METADATA had
|
|
142
|
+
no long description, so its package index page would have been empty; it now
|
|
143
|
+
carries the README with `Description-Content-Type: text/markdown`, and
|
|
144
|
+
`twine check --strict` passes on the wheel and the sdist.
|
|
145
|
+
|
|
146
|
+
### Fixed
|
|
147
|
+
- **`verify-claims` raised `AttributeError: 'str' object has no attribute 'get'` on
|
|
148
|
+
every current collection.** `load_collection()` read only the earlier layout,
|
|
149
|
+
where `collection.yaml` lists skills as mappings. Current releases list skills and
|
|
150
|
+
tools as slugs, keep leaf skills in `leaves/<slug>/SKILL.md`, put the collection
|
|
151
|
+
IRI under `iri`, write evidence spans as plain strings and papers under
|
|
152
|
+
`derived_from` or `provenance.source_papers`. The loader now reads both layouts.
|
|
153
|
+
- SKILL.md frontmatter was split on any `---`, so a quoted value containing it cut
|
|
154
|
+
the YAML short. Only a fence line closes the block now.
|
|
155
|
+
- A tool slug containing the word `path` was indexed as a mapping and raised
|
|
156
|
+
`TypeError`.
|
|
157
|
+
- The round-trip gate counted a claim as resolved only when typed with the
|
|
158
|
+
hardcoded holobiomicslab `Claim` class. It now resolves claims typed with
|
|
159
|
+
indicium's `asb:Claim`, the class ASB's indicium emitter writes.
|
|
160
|
+
- The pretty `verify-claims` FAIL report printed each dangling reference as a
|
|
161
|
+
dataclass repr; it now prints `<skill slug>: <claim IRI>`.
|
|
162
|
+
- **The round-trip gate failed open.** A listed skill with no SKILL.md was dropped
|
|
163
|
+
without a word, and one that failed validation was dropped with a warning, so
|
|
164
|
+
`verify-claims` exited 0 without checking the claim IRIs it listed. Both now fail
|
|
165
|
+
the gate (exit 1, `RoundTripResult.ok` false), and the claim IRIs a skipped
|
|
166
|
+
skill's frontmatter lists are still checked. `RoundTripResult.render()` now
|
|
167
|
+
returns the report `verify-claims` prints.
|
|
168
|
+
- The `verify-claims --help` text named only `metadata.claims` and the
|
|
169
|
+
`skills/<slug>/SKILL.md` layout; it now names the frontmatter `claims` key and
|
|
170
|
+
`leaves/<slug>/SKILL.md`.
|
|
171
|
+
|
|
172
|
+
### Known gaps
|
|
173
|
+
- Claims, evidence spans, tools and papers are typed with the classes the indicium
|
|
174
|
+
shapes target. Skills, which the indicium model does not describe, a claim's
|
|
175
|
+
`super_pattern`, the `name` of skills and tools and the skill-to-evidence link
|
|
176
|
+
`hasEvidence` use this mapper's local names under `INDICIUM_BASE`.
|
|
177
|
+
- Evidence spans carry `indicium:source_doi` and `indicium:paragraph_id`, which
|
|
178
|
+
indicium declares on other classes (`paragraph_id` on Source, `source_doi` on
|
|
179
|
+
Figure, Script and DataAsset). The Evidence shape is open, so no shape checks
|
|
180
|
+
them. `indicium:of_source`, the Evidence-to-Source link indicium models, is not
|
|
181
|
+
written.
|
|
182
|
+
- The skill-to-claim assertion nodes use `SEPIO_Assertion`, `SEPIO_hasSubject` and
|
|
183
|
+
`SEPIO_hasObject`, which are not SEPIO terms; no shape targets them.
|
|
184
|
+
- A paper whose records give different titles is written without `dct:title`, with
|
|
185
|
+
a warning naming its DOI.
|
|
186
|
+
- The `verify-claims` shape-targeted count is graph-wide: one targeted node passes
|
|
187
|
+
it, and instances of subclasses of a targeted class are not counted.
|
|
188
|
+
- A claims-file record without `context` maps to a claim without `asb:context`,
|
|
189
|
+
which the `asb:Claim` shape requires, and the shape reports a violation. ASB's
|
|
190
|
+
own claims carry a context; the mapper writes it when the record has one.
|
|
191
|
+
- Current tool records carry `repo_url`, not `canonical_url`, so the bio.tools
|
|
192
|
+
resolver has nothing to look up for them.
|
|
193
|
+
- No SKILL.md in the current collections lists a claim IRI, so `verify-claims`
|
|
194
|
+
checks none. Metabolomics v2 has 5859 skills and none lists a claim IRI.
|
|
195
|
+
Proteomics v1 and genomics v1 declare `n_claims` totalling 5454 across 558 skills
|
|
196
|
+
and 34070 across 3246 skills, but list no IRI. Each passes with 0 claims
|
|
197
|
+
resolved.
|
|
198
|
+
- `uv lock` and `uv sync` need the indicium checkout beside this one:
|
|
199
|
+
`[tool.uv.sources]` points `indicium-standard` at `../indicium`.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## [0.5.0] - 2026-05-24 (never tagged)
|
|
204
|
+
|
|
205
|
+
### Added
|
|
206
|
+
|
|
207
|
+
- New `indicium_adapters.asb` subpackage: maps ASB-Skill collection
|
|
208
|
+
on-disk artifacts (collection.yaml, SKILL.md frontmatter,
|
|
209
|
+
tools/<slug>.yaml) onto `indicium:Evidence`, `indicium:SoftwareEntity`,
|
|
210
|
+
`indicium:Claim`, `indicium:InformationSource`, and SEPIO skill→claim
|
|
211
|
+
assertions.
|
|
212
|
+
- PROV-O envelope (`prov:wasGeneratedBy`, `prov:wasDerivedFrom`,
|
|
213
|
+
`prov:atTime`) attached to every typed node.
|
|
214
|
+
- `BioToolsResolver` with SQLite cache and `ASB_ADAPTER_OFFLINE` env
|
|
215
|
+
hook for CI determinism.
|
|
216
|
+
- `run_round_trip_check()` CI gate that fails on any dangling
|
|
217
|
+
`metadata.claims` URI in any SKILL.md.
|
|
218
|
+
- `verify-claims` console script for `asb-skill-collections` CI integration.
|
|
219
|
+
|
|
220
|
+
### Notes
|
|
221
|
+
|
|
222
|
+
- Subpackage requires the new optional extra: `pip install -e '.[asb]'`.
|
|
223
|
+
- The reverse (indicium → ASB-Skill hints) adapter is deferred to v1.1.
|
|
224
|
+
- The `SciSkill`→`ASBSkill` Python rename in ASB lands in Wave 2;
|
|
225
|
+
this subpackage works against on-disk artifacts only and is unaffected.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## [0.4.0] - 2026-05-24
|
|
230
|
+
|
|
231
|
+
### Removed
|
|
232
|
+
- `MetabolomicsAdapter` and its `metabolomics.shapes.ttl` and associated tests.
|
|
233
|
+
These have moved to the new `indicium-adapters-metabolomics` package, which
|
|
234
|
+
ships richer enrichment (RefMet+BridgeDb compound index) and adds two sibling
|
|
235
|
+
adapters: `MetaboKGAdapter` and `EMIAdapter`.
|
|
236
|
+
Migration: `pip install indicium-adapters-metabolomics`; the
|
|
237
|
+
`discover_adapters()["metabolomics"]` entry remains available, now sourced
|
|
238
|
+
from the new package.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## [0.3.0] - 2026-05-23
|
|
243
|
+
|
|
244
|
+
### Added
|
|
245
|
+
- `CompositeAdapter`: combines 2+ `DomainAdapter` instances into one that satisfies both
|
|
246
|
+
`DomainAdapter` and `SHACLProvider` protocols. Composition rules: `qualifiers` (union),
|
|
247
|
+
`ontology_prefixes` (merged dict, later adapter wins on key conflict), `extraction_context()`
|
|
248
|
+
(concatenated with double newline), `enrich_claim()` (sequential chain: each adapter
|
|
249
|
+
enriches the output of the previous), `shacl_shapes()` (merged `rdflib.Graph`; adapters
|
|
250
|
+
without `shacl_shapes()` are silently skipped; uses `isinstance(SHACLProvider)` check).
|
|
251
|
+
- `compose_adapters(adapters)`: factory function: returns the single adapter unchanged
|
|
252
|
+
when `len(adapters) == 1` (no wrapping overhead); returns `CompositeAdapter` for 2+;
|
|
253
|
+
raises `ValueError` for an empty list.
|
|
254
|
+
- Both `CompositeAdapter` and `compose_adapters` exported from the top-level
|
|
255
|
+
`indicium_adapters` package.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## [0.2.0] - 2026-05-23
|
|
260
|
+
|
|
261
|
+
### Added
|
|
262
|
+
- `SHACLProvider` Protocol mixin: adapters that implement `shacl_shapes() -> rdflib.Graph` are
|
|
263
|
+
automatically detected by `indicium.validate_graph()` and their shapes are merged into validation.
|
|
264
|
+
- `api_version: int` field on `DomainAdapter` Protocol and `CURRENT_API_VERSION` constant.
|
|
265
|
+
`discover_adapters()` now skips adapters whose `api_version` does not match `CURRENT_API_VERSION`
|
|
266
|
+
and emits a `RuntimeWarning` with upgrade instructions.
|
|
267
|
+
- `MetabolomicsAdapter.shacl_shapes()`: returns the bundled `metabolomics.shapes.ttl` graph
|
|
268
|
+
containing CURIE-format constraints on `asb:subject_ontology_term` / `asb:object_ontology_term`.
|
|
269
|
+
|
|
270
|
+
### Fixed
|
|
271
|
+
- `metabolomics.shapes.ttl` shape target corrected from the inert `sh:targetSubjectsOf CHEBI:is_a`
|
|
272
|
+
to `sh:targetClass asb:Claim` with property shapes on the `asb:{slot}_ontology_term` predicates
|
|
273
|
+
emitted by `claims_to_graph()`.
|
|
274
|
+
- CURIE regex pattern in `metabolomics.shapes.ttl` broadened from `[A-Za-z0-9_]+` to
|
|
275
|
+
`[A-Za-z0-9_.+-]+` in the local part, accommodating PubChem, InChIKey, and other identifiers
|
|
276
|
+
that contain dots, hyphens, or plus signs.
|
|
277
|
+
- `rdflib>=7.0` added as an explicit runtime dependency (was only transitive via `indicium`).
|
|
278
|
+
- `indicium` dependency floor raised from `>=1.0` to `>=1.4`, which is the minimum version that
|
|
279
|
+
provides the `extra_shapes` kwarg required by `SHACLProvider` injection.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## [0.1.0] - 2026-05-20
|
|
284
|
+
|
|
285
|
+
### Added
|
|
286
|
+
- `DomainAdapter` Protocol with `domain_id`, `domain_label`, and `api_version` fields.
|
|
287
|
+
- `discover_adapters()`: entry-point discovery function resolving all `indicium.adapters`
|
|
288
|
+
entry points at import time; returns a `dict[str, DomainAdapter]` keyed by `domain_id`.
|
|
289
|
+
- `MetabolomicsAdapter` with:
|
|
290
|
+
- `enrich_claim()`: annotates `subject` / `object` / `qualifier` slots with CHEBI CURIEs from
|
|
291
|
+
a static compound lookup table (live network lookup planned for a future `[network]` extra).
|
|
292
|
+
- `domain_context` string injected into LLM extraction prompts for metabolomics-aware extraction.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
title: indicium-adapters
|
|
3
|
+
message: "If you use this software, please cite it as below."
|
|
4
|
+
type: software
|
|
5
|
+
version: 0.6.0
|
|
6
|
+
authors:
|
|
7
|
+
- family-names: Nothias
|
|
8
|
+
given-names: Louis-Felix
|
|
9
|
+
email: louis-felix.nothias@cnrs.fr
|
|
10
|
+
orcid: "https://orcid.org/0000-0001-6711-6719"
|
|
11
|
+
repository-code: "https://github.com/HolobiomicsLab/indicium-adapters"
|
|
12
|
+
license: MIT
|
|
13
|
+
keywords:
|
|
14
|
+
- indicium
|
|
15
|
+
- knowledge-graph
|
|
16
|
+
- rdf
|
|
17
|
+
- shacl
|
|
18
|
+
- domain-adapter
|
|
19
|
+
- protocol
|
|
20
|
+
abstract: >-
|
|
21
|
+
Protocol-only core of the indicium domain-adapter ecosystem.
|
|
22
|
+
Defines DomainAdapter and SHACLProvider structural Protocols, the
|
|
23
|
+
CompositeAdapter helper, and the discover_adapters() entry-point
|
|
24
|
+
discovery function. Domain-specific bundles ship in sibling
|
|
25
|
+
indicium-adapters-<domain> packages.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Contributing to indicium-adapters
|
|
2
|
+
|
|
3
|
+
Thanks for your interest!
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
The sibling path in `[tool.uv.sources]` supports contributors who clone
|
|
8
|
+
`indicium` and `indicium-adapters` side by side:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
cd indicium-adapters
|
|
12
|
+
uv sync --extra dev --extra asb
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
In a lone public clone, use `uv sync --no-sources --extra dev --extra asb`
|
|
16
|
+
until the lock is regenerated after the `indicium-standard` 2.0.0 upload.
|
|
17
|
+
Keep `--no-sources` on later `uv run` commands too.
|
|
18
|
+
|
|
19
|
+
## Development workflow
|
|
20
|
+
|
|
21
|
+
1. Create a feature branch from `main`.
|
|
22
|
+
2. Write tests first (TDD). The suite is `pytest`.
|
|
23
|
+
3. Run `uv run ruff check .` and `uv run pytest` before pushing. In a lone
|
|
24
|
+
clone, pass `--no-sources` to both `uv run` commands. CI fails on any ruff
|
|
25
|
+
finding.
|
|
26
|
+
4. Open a PR.
|
|
27
|
+
|
|
28
|
+
## Scope
|
|
29
|
+
|
|
30
|
+
This package is the Protocol-only core. Domain-specific adapters
|
|
31
|
+
(metabolomics, lipidomics, proteomics, ...) live in sibling
|
|
32
|
+
`indicium-adapters-<domain>` repositories. Don't add domain enrichment
|
|
33
|
+
logic here.
|
|
34
|
+
|
|
35
|
+
## Bumping CURRENT_API_VERSION
|
|
36
|
+
|
|
37
|
+
Bumping `CURRENT_API_VERSION` is a coordinated cross-repo release. Plan
|
|
38
|
+
it with the maintainers of every `indicium-adapters-*` package; the README
|
|
39
|
+
lists the ten known at 0.6.0.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Louis-Felix Nothias
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|