Spaces:
Sleeping
Sleeping
Update genesis/api_clients/umls_api.py
Browse files- genesis/api_clients/umls_api.py +48 -17
genesis/api_clients/umls_api.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
# genesis/api_clients/umls_api.py
|
2 |
import os
|
3 |
import requests
|
4 |
-
from typing import List, Dict
|
5 |
|
6 |
UMLS_API_KEY = os.getenv("UMLS_API_KEY") # Your UMLS API key from NIH UTS
|
7 |
UMLS_AUTH_ENDPOINT = "https://utslogin.nlm.nih.gov/cas/v1/api-key"
|
@@ -10,7 +10,7 @@ UMLS_BASE = "https://uts-ws.nlm.nih.gov/rest"
|
|
10 |
session = requests.Session()
|
11 |
|
12 |
# -------------------------
|
13 |
-
#
|
14 |
# -------------------------
|
15 |
def get_umls_ticket_granting_ticket() -> str:
|
16 |
"""
|
@@ -23,8 +23,18 @@ def get_umls_ticket_granting_ticket() -> str:
|
|
23 |
r = session.post(UMLS_AUTH_ENDPOINT, data=params)
|
24 |
r.raise_for_status()
|
25 |
|
26 |
-
#
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
def get_umls_service_ticket(tgt: str) -> str:
|
30 |
"""
|
@@ -33,14 +43,15 @@ def get_umls_service_ticket(tgt: str) -> str:
|
|
33 |
params = {"service": "http://umlsks.nlm.nih.gov"}
|
34 |
r = session.post(tgt, data=params)
|
35 |
r.raise_for_status()
|
36 |
-
return r.text
|
37 |
|
38 |
# -------------------------
|
39 |
-
# Search
|
40 |
# -------------------------
|
41 |
def search_umls(term: str, page_size: int = 5) -> List[Dict]:
|
42 |
"""
|
43 |
-
Search the UMLS Metathesaurus for a given term
|
|
|
44 |
"""
|
45 |
tgt = get_umls_ticket_granting_ticket()
|
46 |
st = get_umls_service_ticket(tgt)
|
@@ -56,19 +67,20 @@ def search_umls(term: str, page_size: int = 5) -> List[Dict]:
|
|
56 |
results = r.json().get("result", {}).get("results", [])
|
57 |
concepts = []
|
58 |
for res in results:
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
|
|
64 |
return concepts
|
65 |
|
66 |
# -------------------------
|
67 |
-
#
|
68 |
# -------------------------
|
69 |
def get_concept_details(cui: str) -> Dict:
|
70 |
"""
|
71 |
-
Fetch
|
72 |
"""
|
73 |
tgt = get_umls_ticket_granting_ticket()
|
74 |
st = get_umls_service_ticket(tgt)
|
@@ -78,7 +90,7 @@ def get_concept_details(cui: str) -> Dict:
|
|
78 |
return r.json().get("result", {})
|
79 |
|
80 |
# -------------------------
|
81 |
-
#
|
82 |
# -------------------------
|
83 |
def get_related_concepts(cui: str) -> List[Dict]:
|
84 |
"""
|
@@ -101,11 +113,11 @@ def get_related_concepts(cui: str) -> List[Dict]:
|
|
101 |
return related
|
102 |
|
103 |
# -------------------------
|
104 |
-
#
|
105 |
# -------------------------
|
106 |
def umls_network(term: str) -> Dict:
|
107 |
"""
|
108 |
-
Build a semantic network for a term:
|
109 |
"""
|
110 |
concepts = search_umls(term)
|
111 |
network = []
|
@@ -124,3 +136,22 @@ def umls_network(term: str) -> Dict:
|
|
124 |
"term": term,
|
125 |
"network": network
|
126 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
# genesis/api_clients/umls_api.py
|
2 |
import os
|
3 |
import requests
|
4 |
+
from typing import List, Dict, Optional
|
5 |
|
6 |
UMLS_API_KEY = os.getenv("UMLS_API_KEY") # Your UMLS API key from NIH UTS
|
7 |
UMLS_AUTH_ENDPOINT = "https://utslogin.nlm.nih.gov/cas/v1/api-key"
|
|
|
10 |
session = requests.Session()
|
11 |
|
12 |
# -------------------------
|
13 |
+
# Authentication Helpers
|
14 |
# -------------------------
|
15 |
def get_umls_ticket_granting_ticket() -> str:
|
16 |
"""
|
|
|
23 |
r = session.post(UMLS_AUTH_ENDPOINT, data=params)
|
24 |
r.raise_for_status()
|
25 |
|
26 |
+
# Extract TGT location from XML
|
27 |
+
if "location" in r.headers:
|
28 |
+
return r.headers["location"]
|
29 |
+
|
30 |
+
# Fallback: parse XML body
|
31 |
+
from xml.etree import ElementTree as ET
|
32 |
+
root = ET.fromstring(r.text)
|
33 |
+
form = root.find(".//form")
|
34 |
+
if form is not None and "action" in form.attrib:
|
35 |
+
return form.attrib["action"]
|
36 |
+
|
37 |
+
raise RuntimeError("Unable to retrieve UMLS TGT. Check API key or response format.")
|
38 |
|
39 |
def get_umls_service_ticket(tgt: str) -> str:
|
40 |
"""
|
|
|
43 |
params = {"service": "http://umlsks.nlm.nih.gov"}
|
44 |
r = session.post(tgt, data=params)
|
45 |
r.raise_for_status()
|
46 |
+
return r.text.strip()
|
47 |
|
48 |
# -------------------------
|
49 |
+
# Search Concepts
|
50 |
# -------------------------
|
51 |
def search_umls(term: str, page_size: int = 5) -> List[Dict]:
|
52 |
"""
|
53 |
+
Search the UMLS Metathesaurus for a given term.
|
54 |
+
Returns a list of concepts with CUI and metadata.
|
55 |
"""
|
56 |
tgt = get_umls_ticket_granting_ticket()
|
57 |
st = get_umls_service_ticket(tgt)
|
|
|
67 |
results = r.json().get("result", {}).get("results", [])
|
68 |
concepts = []
|
69 |
for res in results:
|
70 |
+
if res.get("ui") != "NONE":
|
71 |
+
concepts.append({
|
72 |
+
"name": res.get("name"),
|
73 |
+
"cui": res.get("ui"),
|
74 |
+
"rootSource": res.get("rootSource")
|
75 |
+
})
|
76 |
return concepts
|
77 |
|
78 |
# -------------------------
|
79 |
+
# Concept Details
|
80 |
# -------------------------
|
81 |
def get_concept_details(cui: str) -> Dict:
|
82 |
"""
|
83 |
+
Fetch details for a UMLS CUI (definitions, atoms, semantic types).
|
84 |
"""
|
85 |
tgt = get_umls_ticket_granting_ticket()
|
86 |
st = get_umls_service_ticket(tgt)
|
|
|
90 |
return r.json().get("result", {})
|
91 |
|
92 |
# -------------------------
|
93 |
+
# Related Concepts
|
94 |
# -------------------------
|
95 |
def get_related_concepts(cui: str) -> List[Dict]:
|
96 |
"""
|
|
|
113 |
return related
|
114 |
|
115 |
# -------------------------
|
116 |
+
# Term → Semantic Network
|
117 |
# -------------------------
|
118 |
def umls_network(term: str) -> Dict:
|
119 |
"""
|
120 |
+
Build a semantic network for a term: concepts, details, and related CUIs.
|
121 |
"""
|
122 |
concepts = search_umls(term)
|
123 |
network = []
|
|
|
136 |
"term": term,
|
137 |
"network": network
|
138 |
}
|
139 |
+
|
140 |
+
# -------------------------
|
141 |
+
# Expansion Helper for pipeline.py
|
142 |
+
# -------------------------
|
143 |
+
def expand_with_umls(term: str, max_results: int = 5) -> List[str]:
|
144 |
+
"""
|
145 |
+
Expand a biomedical term into related synonyms & preferred names from UMLS.
|
146 |
+
Used by pipeline.py for ontology enrichment.
|
147 |
+
"""
|
148 |
+
try:
|
149 |
+
concepts = search_umls(term, page_size=max_results)
|
150 |
+
expanded = []
|
151 |
+
for c in concepts:
|
152 |
+
if c["name"] and c["name"].lower() != term.lower():
|
153 |
+
expanded.append(c["name"])
|
154 |
+
return list(set(expanded))
|
155 |
+
except Exception as e:
|
156 |
+
print(f"[UMLS] Expansion failed for '{term}': {e}")
|
157 |
+
return []
|