File size: 2,472 Bytes
5b6700c
67ef408
f96a85c
5b6700c
5755f5b
f96a85c
67ef408
f96a85c
5755f5b
f96a85c
 
67ef408
f96a85c
67ef408
d24e0a6
 
67ef408
f96a85c
 
c37fc6d
f96a85c
 
 
c37fc6d
f96a85c
 
 
 
 
 
 
 
 
 
 
5b6700c
5755f5b
f96a85c
c37fc6d
f96a85c
c37fc6d
f96a85c
 
 
 
 
 
 
 
 
 
 
 
 
5755f5b
 
f96a85c
5755f5b
f96a85c
 
5755f5b
f96a85c
 
 
 
 
 
 
 
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
# genesis/api_clients/bioportal_api.py
import requests
from typing import List, Dict, Optional

BIOPORTAL_BASE_URL = "https://data.bioontology.org"
BIOPORTAL_API_KEY = None  # Load from secrets in Hugging Face or local .env

def search_term(term: str, ontologies: Optional[List[str]] = None, max_results: int = 20) -> List[Dict]:
    """
    Search BioPortal for a term across one or more ontologies.
    If no ontologies specified, searches all available ones.
    """
    headers = {"Authorization": f"apikey token={BIOPORTAL_API_KEY}"}
    params = {
        "q": term,
        "pagesize": max_results
    }
    if ontologies:
        params["ontologies"] = ",".join(ontologies)

    r = requests.get(f"{BIOPORTAL_BASE_URL}/search", headers=headers, params=params)
    r.raise_for_status()
    data = r.json()

    results = []
    for result in data.get("collection", []):
        results.append({
            "pref_label": result.get("prefLabel"),
            "definition": result.get("definition", ["No definition found"])[0],
            "synonyms": result.get("synonym", []),
            "ontology": result.get("links", {}).get("ontology"),
            "iri": result.get("@id"),
            "score": result.get("score", 0)
        })
    return results


def get_concept_details(ontology_acronym: str, concept_id: str) -> Dict:
    """
    Fetch detailed metadata for a specific ontology concept.
    """
    headers = {"Authorization": f"apikey token={BIOPORTAL_API_KEY}"}
    r = requests.get(f"{BIOPORTAL_BASE_URL}/ontologies/{ontology_acronym}/classes/{concept_id}",
                     headers=headers)
    r.raise_for_status()
    data = r.json()

    return {
        "pref_label": data.get("prefLabel"),
        "definition": data.get("definition", ["No definition found"])[0],
        "synonyms": data.get("synonym", []),
        "properties": data.get("properties", {}),
        "relations": data.get("links", {})
    }


def map_to_ontologies(term: str, ontologies: List[str]) -> Dict[str, List[str]]:
    """
    Map a given term to equivalent terms in multiple ontologies.
    Returns a dictionary mapping ontology β†’ list of equivalent labels.
    """
    results = search_term(term, ontologies=ontologies)
    mapping = {}
    for res in results:
        onto_name = res.get("ontology", "Unknown")
        if onto_name not in mapping:
            mapping[onto_name] = []
        mapping[onto_name].append(res.get("pref_label"))
    return mapping