Spaces:
Sleeping
Sleeping
Update genesis/api_clients/bioportal_api.py
Browse files
genesis/api_clients/bioportal_api.py
CHANGED
@@ -1,103 +1,88 @@
|
|
1 |
# genesis/api_clients/bioportal_api.py
|
2 |
import os
|
3 |
import requests
|
4 |
-
from typing import
|
5 |
|
|
|
6 |
BIOPORTAL_BASE = "https://data.bioontology.org"
|
7 |
-
BIOPORTAL_API_KEY = os.getenv("BIOPORTAL_API_KEY") # Saved in Hugging Face / .env
|
8 |
|
9 |
# -------------------------
|
10 |
-
#
|
11 |
# -------------------------
|
12 |
-
def
|
13 |
"""
|
14 |
-
|
15 |
"""
|
16 |
if not BIOPORTAL_API_KEY:
|
17 |
-
raise ValueError("
|
18 |
-
|
19 |
-
|
20 |
-
|
|
|
|
|
|
|
|
|
21 |
r.raise_for_status()
|
22 |
-
return r.json()
|
23 |
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
return
|
37 |
|
38 |
# -------------------------
|
39 |
# Get Term Details
|
40 |
# -------------------------
|
41 |
-
def get_term_details(
|
42 |
"""
|
43 |
-
|
44 |
"""
|
45 |
-
|
|
|
|
|
|
|
|
|
|
|
46 |
|
47 |
# -------------------------
|
48 |
-
#
|
49 |
# -------------------------
|
50 |
-
def
|
51 |
-
"""
|
52 |
-
Retrieve mappings for an ontology term to other ontologies.
|
53 |
"""
|
54 |
-
|
55 |
-
return data.get("collection", [])
|
56 |
-
|
57 |
-
def search_and_map(query: str, ontology: Optional[str] = None) -> List[Dict]:
|
58 |
-
"""
|
59 |
-
Search for a term and retrieve mappings.
|
60 |
"""
|
61 |
-
|
62 |
-
|
63 |
-
for
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
"ontology": t.get("links", {}).get("ontology", ""),
|
68 |
-
"mappings": mappings
|
69 |
-
})
|
70 |
-
return mapped_results
|
71 |
|
72 |
# -------------------------
|
73 |
-
#
|
74 |
# -------------------------
|
75 |
-
def
|
76 |
"""
|
77 |
-
|
78 |
-
This is where cross-domain linking happens.
|
79 |
"""
|
80 |
-
from genesis.api_clients import
|
81 |
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
"
|
86 |
-
|
87 |
-
}
|
88 |
-
|
89 |
-
# Ontology search
|
90 |
-
terms = search_terms(query)
|
91 |
-
if terms:
|
92 |
-
mapped_data["ontology_id"] = terms[0].get("@id", "")
|
93 |
-
|
94 |
-
# Link to ChEMBL molecules
|
95 |
-
mapped_data["drugs"] = chembl_api.search_molecule(query)
|
96 |
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
return mapped_data
|
|
|
1 |
# genesis/api_clients/bioportal_api.py
|
2 |
import os
|
3 |
import requests
|
4 |
+
from typing import List, Dict
|
5 |
|
6 |
+
BIOPORTAL_API_KEY = os.getenv("BIOPORTAL_API_KEY") # Set in Hugging Face secrets or .env
|
7 |
BIOPORTAL_BASE = "https://data.bioontology.org"
|
|
|
8 |
|
9 |
# -------------------------
|
10 |
+
# Search Ontology Terms
|
11 |
# -------------------------
|
12 |
+
def search_ontology(term: str, max_results: int = 5) -> List[Dict]:
|
13 |
"""
|
14 |
+
Search BioPortal for matching ontology terms across multiple vocabularies.
|
15 |
"""
|
16 |
if not BIOPORTAL_API_KEY:
|
17 |
+
raise ValueError("BioPortal API key not set in environment variables.")
|
18 |
+
|
19 |
+
params = {
|
20 |
+
"q": term,
|
21 |
+
"pagesize": max_results,
|
22 |
+
"apikey": BIOPORTAL_API_KEY
|
23 |
+
}
|
24 |
+
r = requests.get(f"{BIOPORTAL_BASE}/search", params=params)
|
25 |
r.raise_for_status()
|
|
|
26 |
|
27 |
+
results = r.json().get("collection", [])
|
28 |
+
terms = []
|
29 |
+
for item in results:
|
30 |
+
terms.append({
|
31 |
+
"prefLabel": item.get("prefLabel"),
|
32 |
+
"ontology": item.get("links", {}).get("ontology"),
|
33 |
+
"definition": item.get("definition", [""])[0] if item.get("definition") else "",
|
34 |
+
"iri": item.get("@id"),
|
35 |
+
"synonyms": item.get("synonym", []),
|
36 |
+
"cui": item.get("cui", []), # UMLS Concept Unique Identifiers if available
|
37 |
+
})
|
38 |
+
|
39 |
+
return terms
|
40 |
|
41 |
# -------------------------
|
42 |
# Get Term Details
|
43 |
# -------------------------
|
44 |
+
def get_term_details(ontology_acronym: str, term_id: str) -> Dict:
|
45 |
"""
|
46 |
+
Get full details for a specific ontology term.
|
47 |
"""
|
48 |
+
params = {
|
49 |
+
"apikey": BIOPORTAL_API_KEY
|
50 |
+
}
|
51 |
+
r = requests.get(f"{BIOPORTAL_BASE}/ontologies/{ontology_acronym}/classes/{term_id}", params=params)
|
52 |
+
r.raise_for_status()
|
53 |
+
return r.json()
|
54 |
|
55 |
# -------------------------
|
56 |
+
# Map Term to UMLS CUI
|
57 |
# -------------------------
|
58 |
+
def map_to_umls(term: str) -> List[str]:
|
|
|
|
|
59 |
"""
|
60 |
+
Map a given term to UMLS Concept Unique Identifiers (CUIs).
|
|
|
|
|
|
|
|
|
|
|
61 |
"""
|
62 |
+
results = search_ontology(term)
|
63 |
+
cuis = []
|
64 |
+
for res in results:
|
65 |
+
if res.get("cui"):
|
66 |
+
cuis.extend(res["cui"])
|
67 |
+
return list(set(cuis))
|
|
|
|
|
|
|
|
|
68 |
|
69 |
# -------------------------
|
70 |
+
# Cross-Domain Semantic Context
|
71 |
# -------------------------
|
72 |
+
def ontology_context(term: str) -> Dict:
|
73 |
"""
|
74 |
+
Return ontology info + UMLS mapping + linked literature from PubMed.
|
|
|
75 |
"""
|
76 |
+
from genesis.api_clients import pubmed_api # Lazy import
|
77 |
|
78 |
+
ontology_terms = search_ontology(term)
|
79 |
+
cuis = []
|
80 |
+
for res in ontology_terms:
|
81 |
+
if res.get("cui"):
|
82 |
+
cuis.extend(res["cui"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
|
84 |
+
return {
|
85 |
+
"ontology_terms": ontology_terms,
|
86 |
+
"umls_cuis": list(set(cuis)),
|
87 |
+
"literature": pubmed_api.search_pubmed(term)
|
88 |
+
}
|
|
|
|