-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathversions.py
More file actions
130 lines (107 loc) · 4.36 KB
/
Copy pathversions.py
File metadata and controls
130 lines (107 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Upstream source version fetcher for kg-phenio.
kg-phenio merges phenio.json with two upheno SSSOM mappings. The receipt
nests phenio's per-ontology versions (read from phenio's `phenio-upstream-
versions.tsv` release asset) under a phenio "build" entry; the two upheno
mapping files appear as peer leaves at the kg-phenio level.
In local development against an unreleased phenio checkout, set
`PHENIO_MANIFEST_PATH` to point at the local TSV (e.g.
`../phenio/src/ontology/phenio-upstream-versions.tsv`). In CI / Jenkins the
manifest is fetched from phenio's latest GitHub release.
"""
from __future__ import annotations
import csv
import os
import re
from pathlib import Path
from typing import Any
from kozahub_metadata_schema import (
now_iso,
version_from_github_release,
version_from_http_last_modified,
)
PHENIO_REPO = "monarch-initiative/phenio"
PHENIO_JSON_URL = f"https://github.com/{PHENIO_REPO}/releases/latest/download/phenio.json"
PHENIO_MANIFEST_URL = f"https://github.com/{PHENIO_REPO}/releases/latest/download/phenio-upstream-versions.tsv"
UPHENO_CROSS_URL = (
"https://data.monarchinitiative.org/mappings/latest/upheno-cross-species.sssom.tsv"
)
UPHENO_SPECIES_IND_URL = (
"https://data.monarchinitiative.org/mappings/latest/upheno-species-independent.sssom.tsv"
)
# Match the date segment in version IRIs. Most ontologies put the date under
# `/releases/YYYY-MM-DD/` (CHEBI, MONDO, RO, …) but BFO uses `/YYYY-MM-DD/`
# directly without the `releases/` prefix, so match any path segment shaped
# like a date.
VERSION_IRI_DATE = re.compile(r"/(\d{4}-\d{2}-\d{2})/")
def _ontology_version(version_info: str, version_iri: str) -> str:
"""Prefer the versionInfo column; fall back to the date in versionIRI."""
vi = (version_info or "").strip()
if vi:
return vi
m = VERSION_IRI_DATE.search(version_iri or "")
if m:
return m.group(1)
return "unknown"
def _fetch_phenio_manifest(timeout: float = 10.0) -> str:
"""Fetch phenio-upstream-versions.tsv. Raises on failure."""
override = os.environ.get("PHENIO_MANIFEST_PATH")
if override:
text = Path(override).read_text()
if not text.strip():
raise RuntimeError(f"PHENIO_MANIFEST_PATH={override} is empty")
return text
import requests
r = requests.get(PHENIO_MANIFEST_URL, allow_redirects=True, timeout=timeout)
r.raise_for_status()
if not r.text.strip():
raise RuntimeError(f"{PHENIO_MANIFEST_URL} returned empty body")
return r.text
def _phenio_ontology_leaves(tsv_text: str) -> list[dict[str, Any]]:
leaves: list[dict[str, Any]] = []
for row in csv.DictReader(tsv_text.splitlines(), delimiter="\t"):
source = (row.get("source") or "").strip()
if not source:
continue
version_iri = (row.get("versionIRI") or "").strip()
leaves.append(
{
"id": f"infores:{source}",
"name": source.upper(),
"urls": [version_iri] if version_iri else [],
"version": _ontology_version(row.get("versionInfo", ""), version_iri),
"version_method": "owl_version_iri",
}
)
return leaves
def get_source_versions() -> list[dict[str, Any]]:
now = now_iso()
# Phenio nested-build entry.
phenio_version, phenio_method = version_from_github_release(PHENIO_REPO)
manifest = _fetch_phenio_manifest()
phenio_entry: dict[str, Any] = {
"id": "phenio",
"name": "PHENIO",
"urls": [PHENIO_JSON_URL],
"version": phenio_version,
"version_method": phenio_method,
"retrieved_at": now,
"sources": _phenio_ontology_leaves(manifest),
}
sources: list[dict[str, Any]] = [phenio_entry]
# Upheno mappings — peer leaves at the kg-phenio level.
for url, infores_id, name in [
(UPHENO_CROSS_URL, "infores:upheno-cross-species", "UPheno cross-species mappings"),
(UPHENO_SPECIES_IND_URL, "infores:upheno-species-independent", "UPheno species-independent mappings"),
]:
ver, method = version_from_http_last_modified(url)
sources.append(
{
"id": infores_id,
"name": name,
"urls": [url],
"version": ver,
"version_method": method,
"retrieved_at": now,
}
)
return sources