evidence-graph 0.1.1__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.
- evidence_graph-0.1.1/.github/ISSUE_TEMPLATE/bug_report.yml +34 -0
- evidence_graph-0.1.1/.github/ISSUE_TEMPLATE/config.yml +5 -0
- evidence_graph-0.1.1/.github/ISSUE_TEMPLATE/feature_request.yml +25 -0
- evidence_graph-0.1.1/.github/PULL_REQUEST_TEMPLATE.md +18 -0
- evidence_graph-0.1.1/.github/dependabot.yml +11 -0
- evidence_graph-0.1.1/.github/workflows/ci.yml +79 -0
- evidence_graph-0.1.1/.github/workflows/release.yml +52 -0
- evidence_graph-0.1.1/.github/workflows/security.yml +79 -0
- evidence_graph-0.1.1/.gitignore +31 -0
- evidence_graph-0.1.1/.gitleaks.toml +24 -0
- evidence_graph-0.1.1/.pre-commit-config.yaml +34 -0
- evidence_graph-0.1.1/CHANGELOG.md +66 -0
- evidence_graph-0.1.1/CODE_OF_CONDUCT.md +83 -0
- evidence_graph-0.1.1/CONTRIBUTING.md +82 -0
- evidence_graph-0.1.1/LICENSE +202 -0
- evidence_graph-0.1.1/NOTICE +21 -0
- evidence_graph-0.1.1/PKG-INFO +234 -0
- evidence_graph-0.1.1/README.md +210 -0
- evidence_graph-0.1.1/SECURITY.md +39 -0
- evidence_graph-0.1.1/corpora/mab-aggregation/MANIFEST.json +307 -0
- evidence_graph-0.1.1/corpora/mab-aggregation/artifacts.json +482 -0
- evidence_graph-0.1.1/corpora/mab-aggregation/chunks.json +37333 -0
- evidence_graph-0.1.1/evidence_graph/__init__.py +198 -0
- evidence_graph-0.1.1/evidence_graph/adjudicate.py +399 -0
- evidence_graph-0.1.1/evidence_graph/biolink.py +133 -0
- evidence_graph-0.1.1/evidence_graph/conflicts.py +364 -0
- evidence_graph-0.1.1/evidence_graph/data/MANIFEST.json +62 -0
- evidence_graph-0.1.1/evidence_graph/data/NOTICE +49 -0
- evidence_graph-0.1.1/evidence_graph/data/chebi.tsv.gz +0 -0
- evidence_graph-0.1.1/evidence_graph/data/cl.tsv.gz +0 -0
- evidence_graph-0.1.1/evidence_graph/data/go.tsv.gz +0 -0
- evidence_graph-0.1.1/evidence_graph/data/hgnc.tsv.gz +0 -0
- evidence_graph-0.1.1/evidence_graph/data/mondo.tsv.gz +0 -0
- evidence_graph-0.1.1/evidence_graph/data/redirects.tsv.gz +0 -0
- evidence_graph-0.1.1/evidence_graph/data/uberon.tsv.gz +0 -0
- evidence_graph-0.1.1/evidence_graph/data/uniprot.tsv.gz +0 -0
- evidence_graph-0.1.1/evidence_graph/evaluation.py +230 -0
- evidence_graph-0.1.1/evidence_graph/evidence.py +47 -0
- evidence_graph-0.1.1/evidence_graph/fair.py +307 -0
- evidence_graph-0.1.1/evidence_graph/graph.py +194 -0
- evidence_graph-0.1.1/evidence_graph/grounding.py +323 -0
- evidence_graph-0.1.1/evidence_graph/kgx.py +382 -0
- evidence_graph-0.1.1/evidence_graph/maintain.py +279 -0
- evidence_graph-0.1.1/evidence_graph/ontology.py +121 -0
- evidence_graph-0.1.1/evidence_graph/pipeline.py +196 -0
- evidence_graph-0.1.1/evidence_graph/provenance.py +282 -0
- evidence_graph-0.1.1/evidence_graph/py.typed +0 -0
- evidence_graph-0.1.1/evidence_graph/relations.py +395 -0
- evidence_graph-0.1.1/evidence_graph/ro_crate_validation.py +149 -0
- evidence_graph-0.1.1/examples/mab-aggregation/README.md +44 -0
- evidence_graph-0.1.1/examples/mab-aggregation/kgx_edges.sample.tsv +15 -0
- evidence_graph-0.1.1/examples/mab-aggregation/kgx_nodes.sample.tsv +25 -0
- evidence_graph-0.1.1/examples/mab-aggregation/open_questions.sample.json +97 -0
- evidence_graph-0.1.1/examples/mab-aggregation/summary.json +23 -0
- evidence_graph-0.1.1/pyproject.toml +58 -0
- evidence_graph-0.1.1/scripts/build_vocabulary.py +329 -0
- evidence_graph-0.1.1/scripts/check_no_runtime_deps.py +79 -0
- evidence_graph-0.1.1/scripts/fetch_pmc_corpus.py +221 -0
- evidence_graph-0.1.1/scripts/run_pipeline.py +108 -0
- evidence_graph-0.1.1/tests/test_adjudicate.py +248 -0
- evidence_graph-0.1.1/tests/test_biolink.py +75 -0
- evidence_graph-0.1.1/tests/test_conflicts.py +277 -0
- evidence_graph-0.1.1/tests/test_evaluation.py +132 -0
- evidence_graph-0.1.1/tests/test_fair.py +131 -0
- evidence_graph-0.1.1/tests/test_graph.py +195 -0
- evidence_graph-0.1.1/tests/test_grounding.py +255 -0
- evidence_graph-0.1.1/tests/test_kgx.py +203 -0
- evidence_graph-0.1.1/tests/test_maintain.py +157 -0
- evidence_graph-0.1.1/tests/test_ontology.py +44 -0
- evidence_graph-0.1.1/tests/test_pipeline.py +148 -0
- evidence_graph-0.1.1/tests/test_provenance.py +150 -0
- evidence_graph-0.1.1/tests/test_relations.py +187 -0
- evidence_graph-0.1.1/tests/test_ro_crate_validation.py +88 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something behaves differently from what its docstring or the README says.
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what-happened
|
|
7
|
+
attributes:
|
|
8
|
+
label: What happened
|
|
9
|
+
description: What you expected, and what you got instead.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: reproduce
|
|
14
|
+
attributes:
|
|
15
|
+
label: Minimal reproduction
|
|
16
|
+
description: >
|
|
17
|
+
The smallest input that shows the problem. Please use synthetic text — never paste
|
|
18
|
+
unpublished research, patient data, or anything under an NDA into a public issue.
|
|
19
|
+
render: python
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
- type: input
|
|
23
|
+
id: version
|
|
24
|
+
attributes:
|
|
25
|
+
label: Version
|
|
26
|
+
description: "`pip show evidence-graph`, or the commit SHA."
|
|
27
|
+
validations:
|
|
28
|
+
required: true
|
|
29
|
+
- type: input
|
|
30
|
+
id: python
|
|
31
|
+
attributes:
|
|
32
|
+
label: Python version
|
|
33
|
+
validations:
|
|
34
|
+
required: true
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a capability that fits the library's scope.
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: The problem
|
|
9
|
+
description: What you are trying to do that the library makes hard or impossible.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: proposal
|
|
14
|
+
attributes:
|
|
15
|
+
label: Proposed shape
|
|
16
|
+
description: Roughly what the API would look like, if you have a view.
|
|
17
|
+
- type: checkboxes
|
|
18
|
+
id: scope
|
|
19
|
+
attributes:
|
|
20
|
+
label: Scope check
|
|
21
|
+
description: >
|
|
22
|
+
The library is deliberately narrow — see [CONTRIBUTING.md](../blob/main/CONTRIBUTING.md#scope).
|
|
23
|
+
options:
|
|
24
|
+
- label: This needs no network access, no credentials, and no model at import time.
|
|
25
|
+
- label: This does not require knowing about users, tenants, or requests.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## What this changes
|
|
2
|
+
|
|
3
|
+
<!-- One or two sentences. What behaviour is different after this merges? -->
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
<!-- The problem, not the patch. If it fixes an issue, link it. -->
|
|
8
|
+
|
|
9
|
+
## Checklist
|
|
10
|
+
|
|
11
|
+
- [ ] Tests cover the change, and `python -m unittest discover -s tests` passes.
|
|
12
|
+
- [ ] `ruff check .` passes.
|
|
13
|
+
- [ ] No new runtime dependency (`python scripts/check_no_runtime_deps.py` passes). If the change
|
|
14
|
+
needs a model, a network call, or a credential, it is injected through a Protocol rather than
|
|
15
|
+
imported here — see [CONTRIBUTING.md](../CONTRIBUTING.md#scope).
|
|
16
|
+
- [ ] Nothing secret, private, or customer-identifying is in the diff, including in test fixtures.
|
|
17
|
+
- [ ] If this changes how an edge is asserted or abstained, the reasoning is stated in the PR body
|
|
18
|
+
and reflected in the docstring.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# The library has no runtime dependencies, so the supply-chain surface that actually exists is
|
|
4
|
+
# the CI workflows. A stale pinned action is the realistic risk here, not a stale package.
|
|
5
|
+
- package-ecosystem: github-actions
|
|
6
|
+
directory: "/"
|
|
7
|
+
schedule:
|
|
8
|
+
interval: weekly
|
|
9
|
+
commit-message:
|
|
10
|
+
prefix: "ci"
|
|
11
|
+
labels: ["dependencies", "ci"]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
# Least privilege: nothing in this workflow writes to the repository.
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
lint:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v7
|
|
21
|
+
- uses: actions/setup-python@v7
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.12"
|
|
24
|
+
- run: pip install ruff==0.16.7
|
|
25
|
+
# `ruff check` only. There is deliberately no `ruff format --check`: this code must stay
|
|
26
|
+
# diffable against its origin in the SciWay codebase, and a wholesale reformat would make
|
|
27
|
+
# the first round of review impossible to read.
|
|
28
|
+
- run: ruff check .
|
|
29
|
+
|
|
30
|
+
test:
|
|
31
|
+
runs-on: ${{ matrix.os }}
|
|
32
|
+
strategy:
|
|
33
|
+
fail-fast: false
|
|
34
|
+
matrix:
|
|
35
|
+
os: [ubuntu-latest]
|
|
36
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
37
|
+
include:
|
|
38
|
+
# One Windows leg, because the library handles file paths and text encodings and those
|
|
39
|
+
# are where a "pure stdlib, works everywhere" claim usually turns out to be false.
|
|
40
|
+
- os: windows-latest
|
|
41
|
+
python-version: "3.12"
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v7
|
|
44
|
+
- uses: actions/setup-python@v7
|
|
45
|
+
with:
|
|
46
|
+
python-version: ${{ matrix.python-version }}
|
|
47
|
+
# No install step: the library and its tests are standard-library only. If this line ever
|
|
48
|
+
# needs a `pip install`, the zero-dependency guarantee has been broken — see the job below.
|
|
49
|
+
- name: Run test suite
|
|
50
|
+
run: python -m unittest discover -s tests -v
|
|
51
|
+
|
|
52
|
+
no-runtime-deps:
|
|
53
|
+
# The zero-dependency promise is a design constraint (see pyproject.toml), so it gets a test.
|
|
54
|
+
# Without one it erodes the first time somebody reaches for a convenience library.
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v7
|
|
58
|
+
- uses: actions/setup-python@v7
|
|
59
|
+
with:
|
|
60
|
+
python-version: "3.12"
|
|
61
|
+
- run: python scripts/check_no_runtime_deps.py
|
|
62
|
+
|
|
63
|
+
build:
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/checkout@v7
|
|
67
|
+
- uses: actions/setup-python@v7
|
|
68
|
+
with:
|
|
69
|
+
python-version: "3.12"
|
|
70
|
+
- run: pip install build twine
|
|
71
|
+
- run: python -m build
|
|
72
|
+
# Catches a malformed README or bad metadata before it reaches PyPI, where a release
|
|
73
|
+
# cannot be replaced, only yanked.
|
|
74
|
+
- run: twine check dist/*
|
|
75
|
+
- uses: actions/upload-artifact@v7
|
|
76
|
+
with:
|
|
77
|
+
name: dist
|
|
78
|
+
path: dist/
|
|
79
|
+
retention-days: 7
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Publishing a GitHub release uploads that version to PyPI. Trusted Publishing (OIDC) does the
|
|
4
|
+
# upload, so there is no API token anywhere: PyPI accepts it only from this workflow file, in this
|
|
5
|
+
# repository, running in the `pypi` environment, as registered on the project's publishing page.
|
|
6
|
+
# A failed upload is retried with "Re-run failed jobs"; the built files are reused, not rebuilt.
|
|
7
|
+
on:
|
|
8
|
+
release:
|
|
9
|
+
types: [published]
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v7
|
|
19
|
+
- uses: actions/setup-python@v7
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
- name: Tag matches the package version
|
|
23
|
+
# PyPI never lets a version be replaced, only yanked, so a mismatch is caught here.
|
|
24
|
+
run: |
|
|
25
|
+
version=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
|
|
26
|
+
if [ "v${version}" != "${GITHUB_REF_NAME}" ]; then
|
|
27
|
+
echo "release tag ${GITHUB_REF_NAME} does not match pyproject version ${version}"; exit 1
|
|
28
|
+
fi
|
|
29
|
+
- run: python -m unittest discover -s tests
|
|
30
|
+
- run: python scripts/check_no_runtime_deps.py
|
|
31
|
+
- run: pip install build twine
|
|
32
|
+
- run: python -m build
|
|
33
|
+
- run: twine check --strict dist/*
|
|
34
|
+
- uses: actions/upload-artifact@v7
|
|
35
|
+
with:
|
|
36
|
+
name: dist
|
|
37
|
+
path: dist/
|
|
38
|
+
|
|
39
|
+
publish:
|
|
40
|
+
needs: build
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
environment:
|
|
43
|
+
name: pypi
|
|
44
|
+
url: https://pypi.org/project/evidence-graph/
|
|
45
|
+
permissions:
|
|
46
|
+
id-token: write # the OIDC token PyPI exchanges for a short-lived upload credential
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/download-artifact@v8
|
|
49
|
+
with:
|
|
50
|
+
name: dist
|
|
51
|
+
path: dist/
|
|
52
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: Security
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
schedule:
|
|
8
|
+
# Weekly, so a rule set that learns about a new credential format still scans this history,
|
|
9
|
+
# and CodeQL re-runs against updated queries without waiting for a commit.
|
|
10
|
+
- cron: "17 5 * * 1"
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: security-${{ github.ref }}
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
secrets:
|
|
21
|
+
name: Secret scan (full history)
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v7
|
|
25
|
+
with:
|
|
26
|
+
# Full history. Scanning only the tip would miss a credential that was committed and then
|
|
27
|
+
# "removed" in a later commit, which is exactly the case that matters: the object is still
|
|
28
|
+
# in the pack file and still public.
|
|
29
|
+
fetch-depth: 0
|
|
30
|
+
# The gitleaks GitHub Action requires a paid licence key for organisation-owned repos. The
|
|
31
|
+
# gitleaks binary itself is MIT and free, so we install it directly and pin both the version
|
|
32
|
+
# and its checksum. To upgrade: bump VERSION, then take the new hash from
|
|
33
|
+
# https://github.com/gitleaks/gitleaks/releases/download/v<VERSION>/gitleaks_<VERSION>_checksums.txt
|
|
34
|
+
- name: Install gitleaks
|
|
35
|
+
env:
|
|
36
|
+
VERSION: "8.30.1"
|
|
37
|
+
SHA256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb"
|
|
38
|
+
run: |
|
|
39
|
+
set -euo pipefail
|
|
40
|
+
curl -fsSL -o gitleaks.tar.gz \
|
|
41
|
+
"https://github.com/gitleaks/gitleaks/releases/download/v${VERSION}/gitleaks_${VERSION}_linux_x64.tar.gz"
|
|
42
|
+
echo "${SHA256} gitleaks.tar.gz" | sha256sum -c -
|
|
43
|
+
tar -xzf gitleaks.tar.gz gitleaks
|
|
44
|
+
sudo install -m 0755 gitleaks /usr/local/bin/gitleaks
|
|
45
|
+
gitleaks version
|
|
46
|
+
- name: Scan git history
|
|
47
|
+
# --redact so a finding never echoes the credential into public build logs, which would
|
|
48
|
+
# turn the detector into a second disclosure.
|
|
49
|
+
run: gitleaks git --redact --verbose --config .gitleaks.toml .
|
|
50
|
+
- name: Scan the working tree
|
|
51
|
+
# Catches an unstaged or newly added file that history scanning would not see.
|
|
52
|
+
run: gitleaks dir --redact --verbose --config .gitleaks.toml .
|
|
53
|
+
|
|
54
|
+
codeql:
|
|
55
|
+
name: CodeQL
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
permissions:
|
|
58
|
+
contents: read
|
|
59
|
+
security-events: write # required to upload results to the Security tab
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@v7
|
|
62
|
+
- uses: github/codeql-action/init@v4
|
|
63
|
+
with:
|
|
64
|
+
languages: python
|
|
65
|
+
queries: security-extended
|
|
66
|
+
- uses: github/codeql-action/analyze@v4
|
|
67
|
+
|
|
68
|
+
dependency-review:
|
|
69
|
+
name: Dependency review
|
|
70
|
+
if: github.event_name == 'pull_request'
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
steps:
|
|
73
|
+
- uses: actions/checkout@v7
|
|
74
|
+
# A no-op today (the library has zero runtime dependencies) and that is the point: the first
|
|
75
|
+
# pull request that adds one gets its licence and advisories reviewed automatically.
|
|
76
|
+
- uses: actions/dependency-review-action@v5
|
|
77
|
+
with:
|
|
78
|
+
fail-on-severity: moderate
|
|
79
|
+
allow-licenses: Apache-2.0, MIT, BSD-2-Clause, BSD-3-Clause, ISC, PSF-2.0
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
.pytest_cache/
|
|
10
|
+
.ruff_cache/
|
|
11
|
+
.mypy_cache/
|
|
12
|
+
.coverage
|
|
13
|
+
htmlcov/
|
|
14
|
+
|
|
15
|
+
# Secrets — belt and braces. Nothing in this repo should ever need one, and the secret scan
|
|
16
|
+
# (.github/workflows/security.yml) fails the build if one is committed anyway.
|
|
17
|
+
.env
|
|
18
|
+
.env.*
|
|
19
|
+
!.env.example
|
|
20
|
+
*.pem
|
|
21
|
+
*.key
|
|
22
|
+
*.p12
|
|
23
|
+
*.pfx
|
|
24
|
+
credentials.json
|
|
25
|
+
service-account*.json
|
|
26
|
+
|
|
27
|
+
# Editors / OS
|
|
28
|
+
.idea/
|
|
29
|
+
.vscode/
|
|
30
|
+
.DS_Store
|
|
31
|
+
*.swp
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# gitleaks configuration for evidence-graph.
|
|
2
|
+
#
|
|
3
|
+
# The library holds no credentials by design: it never opens a socket and never authenticates, so
|
|
4
|
+
# any secret-shaped string reaching this repo is a mistake. We therefore run the full default rule
|
|
5
|
+
# set and keep the allowlist deliberately small — a broad allowlist is how secret scanning quietly
|
|
6
|
+
# stops working.
|
|
7
|
+
|
|
8
|
+
title = "evidence-graph"
|
|
9
|
+
|
|
10
|
+
[extend]
|
|
11
|
+
useDefault = true
|
|
12
|
+
|
|
13
|
+
[allowlist]
|
|
14
|
+
description = "Documented placeholders only. Add an entry only with a comment saying why it is safe."
|
|
15
|
+
regexes = [
|
|
16
|
+
# Documentation and test fixtures use obvious non-secrets. These patterns must be self-evidently
|
|
17
|
+
# fake; never allowlist a string that could plausibly be real.
|
|
18
|
+
'''(?i)(example|placeholder|dummy|fake|redacted|your[-_]?(key|token|secret)[-_]?here)''',
|
|
19
|
+
'''^x{8,}$''',
|
|
20
|
+
]
|
|
21
|
+
paths = [
|
|
22
|
+
'''^LICENSE$''',
|
|
23
|
+
'''^NOTICE$''',
|
|
24
|
+
]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Local guardrails. Install once with: pre-commit install
|
|
2
|
+
#
|
|
3
|
+
# These run the same checks CI runs, so a mistake is caught before it reaches a public commit.
|
|
4
|
+
# The secret scan is the one that matters most here: once a credential is pushed to a public repo
|
|
5
|
+
# it must be treated as compromised, and rewriting history does not undo that.
|
|
6
|
+
default_install_hook_types: [pre-commit, pre-push]
|
|
7
|
+
|
|
8
|
+
repos:
|
|
9
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
10
|
+
rev: v6.0.0
|
|
11
|
+
hooks:
|
|
12
|
+
- id: trailing-whitespace
|
|
13
|
+
- id: end-of-file-fixer
|
|
14
|
+
- id: check-yaml
|
|
15
|
+
- id: check-toml
|
|
16
|
+
- id: check-merge-conflict
|
|
17
|
+
- id: check-case-conflict
|
|
18
|
+
- id: detect-private-key
|
|
19
|
+
- id: check-added-large-files
|
|
20
|
+
# 8 MB, to admit the vendored vocabulary files under evidence_graph/data/ (ChEBI is ~6.9 MB).
|
|
21
|
+
# Code and fixtures should stay far below this; if a source file approaches it, something
|
|
22
|
+
# that belongs in a build step has been committed instead.
|
|
23
|
+
args: ["--maxkb=8192"]
|
|
24
|
+
|
|
25
|
+
- repo: https://github.com/gitleaks/gitleaks
|
|
26
|
+
rev: v8.30.1
|
|
27
|
+
hooks:
|
|
28
|
+
- id: gitleaks
|
|
29
|
+
|
|
30
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
31
|
+
rev: v0.16.7
|
|
32
|
+
hooks:
|
|
33
|
+
- id: ruff
|
|
34
|
+
args: ["--fix"]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.1 — 2026-11-03
|
|
4
|
+
|
|
5
|
+
The first release on PyPI. Packaging only: the library code is the same as in 0.1.0, which was
|
|
6
|
+
tagged but never uploaded.
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- `pip install evidence-graph` works. Releases are uploaded by `.github/workflows/release.yml`
|
|
11
|
+
through PyPI Trusted Publishing, so no upload token exists in the repository or its secrets.
|
|
12
|
+
- Added the `py.typed` marker. The `Typing :: Typed` classifier already claimed the package was
|
|
13
|
+
typed, but without the marker type checkers ignored its annotations.
|
|
14
|
+
- Dropped the `License ::` classifier. `license = "Apache-2.0"` is the PEP 639 declaration, and
|
|
15
|
+
the classifier is deprecated next to it.
|
|
16
|
+
- README links are absolute, so they also resolve on the PyPI project page.
|
|
17
|
+
|
|
18
|
+
## 0.1.0 — 2026-09-14
|
|
19
|
+
|
|
20
|
+
First release. Extracted from [SciWay](https://sciway.software), then extended with the pieces a
|
|
21
|
+
biomedical knowledge graph actually needs.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **`grounding`** — surface strings to MONDO, ChEBI, GO, UBERON, CL, HGNC and UniProt CURIEs, with
|
|
26
|
+
the Biolink category each implies. 369,627 terms vendored as 10.8 MB of gzipped TSV, read with
|
|
27
|
+
stdlib gzip. Refuses most strings; reports ambiguity rather than resolving it; no edit-distance
|
|
28
|
+
fallback.
|
|
29
|
+
- **`biolink`** — Biolink Model 4.4.4 categories, predicates and CURIE typing. Returns None for the
|
|
30
|
+
~50 prefixes declared by several classes instead of guessing.
|
|
31
|
+
- **`adjudicate`** — assert / abstain / conflict per candidate edge over an `EdgeScorer` Protocol.
|
|
32
|
+
Default scorer is keyless and deterministic and is explicit that it scores grounding, not truth.
|
|
33
|
+
- **`maintain`** — re-runs that append revisions instead of overwriting. Edges are weakened,
|
|
34
|
+
contradicted or withdrawn, never silently deleted.
|
|
35
|
+
- **`evaluation`** — edge-level precision as a function of abstention, against an explicit
|
|
36
|
+
no-abstention baseline, with a dependency-free SVG renderer.
|
|
37
|
+
- **`kgx`** — KGX interchange in TSV and JSON Lines, including the Biolink-required
|
|
38
|
+
`knowledge_level` and `agent_type` that most KGX files omit.
|
|
39
|
+
- **`pipeline`** — the whole spine in one call, plus `scripts/run_pipeline.py`.
|
|
40
|
+
- **`evidence`** — `RetrievalHit` as the library's public input type.
|
|
41
|
+
- **`ro_crate_validation`** — the RO-Crate structural validator, decoupled from any application.
|
|
42
|
+
- Corpus builder for the PubMed Central Open Access subset on AWS Open Data, filtering on licence.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
Four defects that only a real corpus exposed, three of them in code that was already in production:
|
|
47
|
+
|
|
48
|
+
- `relations` truncated evidence quotes to the first 160 characters while the matched value could
|
|
49
|
+
be anywhere in the passage, so **a citation did not necessarily contain what it was cited for**.
|
|
50
|
+
Quotes are now windowed on the match. Adjudicated coverage moved from 6.5% to 53.8%.
|
|
51
|
+
- Evidence notes carried the normalised entity key, which by construction never appears in the
|
|
52
|
+
source text, making those citations unverifiable. Each side now quotes its own surface form.
|
|
53
|
+
- The entity and measurement grammars matched prose and identifiers: `at 0.01%` became an entity,
|
|
54
|
+
`PMC12345` and `IgG1` became measured quantities. Candidate edges fell from 18,191 to 12,185.
|
|
55
|
+
- `adjudicate` treated descriptive trigger notes as verifiable claims about the quote, and required
|
|
56
|
+
a normalised label to appear in prose where it never does.
|
|
57
|
+
|
|
58
|
+
Plus, in new code: `Vocabulary.__len__` made an empty vocabulary falsy, so `vocabulary or
|
|
59
|
+
load_vocabulary()` silently loaded the real data; and lowercase prose grounded to gene symbols
|
|
60
|
+
(`for` to WWOX) until surface shape was required for symbol vocabularies.
|
|
61
|
+
|
|
62
|
+
### Known limitations
|
|
63
|
+
|
|
64
|
+
- No gold standard for the bundled corpus, so no published precision figure.
|
|
65
|
+
- The `sciway:` JSON-LD namespace in RO-Crate and PROV-O output, and the `id`/`chunk_id` key
|
|
66
|
+
inconsistency between chunks and hits, are both inherited and both breaking changes to fix.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
|
|
6
|
+
|
|
7
|
+
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
|
8
|
+
|
|
9
|
+
## Our Standards
|
|
10
|
+
|
|
11
|
+
Examples of behavior that contributes to a positive environment for our community include:
|
|
12
|
+
|
|
13
|
+
* Demonstrating empathy and kindness toward other people
|
|
14
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
15
|
+
* Giving and gracefully accepting constructive feedback
|
|
16
|
+
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
|
17
|
+
* Focusing on what is best not just for us as individuals, but for the overall community
|
|
18
|
+
|
|
19
|
+
Examples of unacceptable behavior include:
|
|
20
|
+
|
|
21
|
+
* The use of sexualized language or imagery, and sexual attention or advances of any kind
|
|
22
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
23
|
+
* Public or private harassment
|
|
24
|
+
* Publishing others' private information, such as a physical or email address, without their explicit permission
|
|
25
|
+
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
|
26
|
+
|
|
27
|
+
## Enforcement Responsibilities
|
|
28
|
+
|
|
29
|
+
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
|
30
|
+
|
|
31
|
+
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
|
|
32
|
+
|
|
33
|
+
## Scope
|
|
34
|
+
|
|
35
|
+
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
|
|
36
|
+
|
|
37
|
+
## Enforcement
|
|
38
|
+
|
|
39
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at hello@sciway.software. All complaints will be reviewed and investigated promptly and fairly.
|
|
40
|
+
|
|
41
|
+
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
|
|
42
|
+
|
|
43
|
+
## Enforcement Guidelines
|
|
44
|
+
|
|
45
|
+
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
|
|
46
|
+
|
|
47
|
+
### 1. Correction
|
|
48
|
+
|
|
49
|
+
**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
|
|
50
|
+
|
|
51
|
+
**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
|
|
52
|
+
|
|
53
|
+
### 2. Warning
|
|
54
|
+
|
|
55
|
+
**Community Impact**: A violation through a single incident or series of actions.
|
|
56
|
+
|
|
57
|
+
**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
|
|
58
|
+
|
|
59
|
+
### 3. Temporary Ban
|
|
60
|
+
|
|
61
|
+
**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
|
|
62
|
+
|
|
63
|
+
**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
|
|
64
|
+
|
|
65
|
+
### 4. Permanent Ban
|
|
66
|
+
|
|
67
|
+
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
|
68
|
+
|
|
69
|
+
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
|
70
|
+
|
|
71
|
+
## Attribution
|
|
72
|
+
|
|
73
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
|
74
|
+
|
|
75
|
+
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
|
76
|
+
|
|
77
|
+
For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
|
|
78
|
+
|
|
79
|
+
[homepage]: https://www.contributor-covenant.org
|
|
80
|
+
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
|
81
|
+
[Mozilla CoC]: https://github.com/mozilla/diversity
|
|
82
|
+
[FAQ]: https://www.contributor-covenant.org/faq
|
|
83
|
+
[translations]: https://www.contributor-covenant.org/translations
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Contributing to evidence-graph
|
|
2
|
+
|
|
3
|
+
Thanks for looking. This is a research library at 0.x: the API will change, and there is no support
|
|
4
|
+
SLA. Issues and pull requests are welcome on that understanding.
|
|
5
|
+
|
|
6
|
+
## Scope
|
|
7
|
+
|
|
8
|
+
The library is deliberately narrow, and most of the review effort on a pull request goes into
|
|
9
|
+
whether a change belongs here at all. Two rules define the boundary:
|
|
10
|
+
|
|
11
|
+
**1. No network, no credentials, no models.** The library never opens a socket, never reads an API
|
|
12
|
+
key, and never imports a model at runtime. It has zero runtime dependencies and CI enforces that
|
|
13
|
+
(`scripts/check_no_runtime_deps.py` walks every import in the package and fails on anything outside the
|
|
14
|
+
standard library).
|
|
15
|
+
|
|
16
|
+
This is not minimalism for its own sake. A library that decides whether evidence supports a claim
|
|
17
|
+
has to be auditable by the scientist relying on it, and has to run inside an air-gapped lab. The
|
|
18
|
+
moment it needs a key, both properties are gone.
|
|
19
|
+
|
|
20
|
+
If your change genuinely needs a model — an LLM that scores whether a chunk supports an edge, say —
|
|
21
|
+
the right shape is a `Protocol` defined here and implemented by the caller. The library states what
|
|
22
|
+
it needs; it does not reach out and get it.
|
|
23
|
+
|
|
24
|
+
**2. No knowledge of users, tenants, projects, or requests.** Those concepts belong to whatever
|
|
25
|
+
application embeds this. The library's world is text with provenance in, asserted edges with
|
|
26
|
+
lineage out.
|
|
27
|
+
|
|
28
|
+
## What a good contribution looks like
|
|
29
|
+
|
|
30
|
+
- **A failing test first.** Every module here is deterministic and pure, so almost any bug can be
|
|
31
|
+
written as a test before it is fixed. If it cannot, say why in the issue.
|
|
32
|
+
- **Evidence stays attached.** No code path may produce an edge, a value, or a quote that is not
|
|
33
|
+
traceable to a specific location in a source document. A convenience that drops provenance will
|
|
34
|
+
be rejected even when it is faster.
|
|
35
|
+
- **Abstention is a feature.** When the evidence does not support an assertion, the correct output
|
|
36
|
+
is an abstention or a recorded conflict. Pull requests that improve coverage by lowering the bar
|
|
37
|
+
for assertion need to show the precision cost, not just the coverage gain.
|
|
38
|
+
- **Synthetic fixtures only.** Never commit real unpublished research, patient data, or anything
|
|
39
|
+
under an NDA, including in tests.
|
|
40
|
+
|
|
41
|
+
## Development
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://github.com/SciWay-platform/evidence-graph.git
|
|
45
|
+
cd evidence-graph
|
|
46
|
+
|
|
47
|
+
python -m unittest discover -s tests -v # the suite; standard library only, no install needed
|
|
48
|
+
pip install ruff==0.16.7 && ruff check . # lint
|
|
49
|
+
python scripts/check_no_runtime_deps.py # the zero-dependency guard
|
|
50
|
+
|
|
51
|
+
pip install pre-commit && pre-commit install # optional, runs the same checks plus a secret scan
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
There is no build step and nothing to install to run the tests. If that ever stops being true,
|
|
55
|
+
something has gone wrong.
|
|
56
|
+
|
|
57
|
+
## Style
|
|
58
|
+
|
|
59
|
+
Match the surrounding code. Concretely, for this repo that means:
|
|
60
|
+
|
|
61
|
+
- A module docstring that states what the module is for and why it exists in that form. The
|
|
62
|
+
docstrings here carry design reasoning deliberately, because the *why* is the part that decays.
|
|
63
|
+
- Type hints on public functions, `from __future__ import annotations` at the top.
|
|
64
|
+
- Comments explain decisions, not mechanics.
|
|
65
|
+
- `ruff check .` must pass. There is no enforced formatter: line-length errors are switched off
|
|
66
|
+
because much of this code is regex grammar and vocabulary tables where a hard wrap hurts.
|
|
67
|
+
|
|
68
|
+
## Licensing
|
|
69
|
+
|
|
70
|
+
By contributing you agree that your contribution is licensed under the
|
|
71
|
+
[Apache License 2.0](LICENSE), the same licence as the project. There is no CLA.
|
|
72
|
+
|
|
73
|
+
Code adapted from another project must keep its attribution and be recorded in [NOTICE](NOTICE),
|
|
74
|
+
with the upstream licence reproduced in full.
|
|
75
|
+
|
|
76
|
+
## Security
|
|
77
|
+
|
|
78
|
+
Do not report vulnerabilities in a public issue. See [SECURITY.md](SECURITY.md).
|
|
79
|
+
|
|
80
|
+
## Code of conduct
|
|
81
|
+
|
|
82
|
+
Participation is covered by the [Contributor Covenant](CODE_OF_CONDUCT.md).
|