mgbam commited on
Commit
ae6d61e
Β·
verified Β·
1 Parent(s): 701c750

Update genesis/api_clients/umls_api.py

Browse files
Files changed (1) hide show
  1. genesis/api_clients/umls_api.py +55 -52
genesis/api_clients/umls_api.py CHANGED
@@ -1,86 +1,89 @@
1
  # genesis/api_clients/umls_api.py
2
  import os
3
  import requests
4
- from typing import Dict, List, Optional
5
 
6
- # UMLS API
 
7
  UMLS_BASE = "https://uts-ws.nlm.nih.gov/rest"
8
- UMLS_API_KEY = os.getenv("UMLS_API_KEY") # Add this to your Hugging Face secrets or .env
9
 
10
- if not UMLS_API_KEY:
11
- raise EnvironmentError("UMLS_API_KEY is missing. Add it to your environment variables or Hugging Face secrets.")
12
-
13
- # UMLS requires ticket-granting service for authentication
14
  def get_tgt() -> str:
15
  """
16
- Obtain a Ticket Granting Ticket (TGT) for UMLS authentication.
17
  """
18
- r = requests.post("https://utslogin.nlm.nih.gov/cas/v1/api-key", data={"apikey": UMLS_API_KEY})
 
19
  r.raise_for_status()
20
- from xml.etree import ElementTree
21
- root = ElementTree.fromstring(r.text)
22
- return root.attrib.get("action")
23
-
24
 
25
- def get_service_ticket(tgt: str) -> str:
26
  """
27
- Get a single-use service ticket for API requests.
28
  """
29
- r = requests.post(tgt, data={"service": "http://umlsks.nlm.nih.gov"})
 
30
  r.raise_for_status()
31
  return r.text
32
 
33
-
34
- def search_umls(query: str, max_results: int = 10) -> List[Dict]:
 
 
35
  """
36
- Search UMLS Metathesaurus for a term and return CUIs and names.
37
  """
38
  tgt = get_tgt()
39
- ticket = get_service_ticket(tgt)
40
- params = {"string": query, "ticket": ticket, "pageSize": max_results}
41
-
 
 
 
42
  r = requests.get(f"{UMLS_BASE}/search/current", params=params)
43
  r.raise_for_status()
44
- results = r.json().get("result", {}).get("results", [])
45
-
46
- return [
47
- {
48
- "ui": item.get("ui"),
 
49
  "name": item.get("name"),
50
  "rootSource": item.get("rootSource")
51
- }
52
- for item in results if item.get("ui") != "NONE"
53
- ]
54
-
55
 
56
- def get_concept_details(cui: str) -> Dict:
57
  """
58
- Get full details for a given CUI (Concept Unique Identifier).
59
- Includes synonyms, definitions, and mappings.
60
  """
61
  tgt = get_tgt()
62
- ticket = get_service_ticket(tgt)
63
-
64
- r = requests.get(f"{UMLS_BASE}/content/current/CUI/{cui}", params={"ticket": ticket})
65
  r.raise_for_status()
66
- return r.json().get("result", {})
67
 
68
-
69
- def map_between_ontologies(cui: str) -> List[Dict]:
70
  """
71
- Given a CUI, return cross-ontology mappings (e.g., SNOMED β†’ MeSH β†’ ICD).
72
  """
73
  tgt = get_tgt()
74
- ticket = get_service_ticket(tgt)
75
-
76
- r = requests.get(f"{UMLS_BASE}/crosswalk/current/source/{cui}", params={"ticket": ticket})
77
  r.raise_for_status()
78
- return r.json().get("result", [])
79
-
80
 
81
- def normalize_term(term: str) -> Optional[Dict]:
82
- """
83
- Normalize a free-text biomedical term to its canonical CUI and return metadata.
84
- """
85
- matches = search_umls(term, max_results=1)
86
- return matches[0] if matches else None
 
 
 
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") # Set in Hugging Face secrets or .env
7
+ UMLS_AUTH_ENDPOINT = "https://utslogin.nlm.nih.gov/cas/v1/api-key"
8
  UMLS_BASE = "https://uts-ws.nlm.nih.gov/rest"
 
9
 
10
+ # -------------------------
11
+ # AUTHENTICATION
12
+ # -------------------------
 
13
  def get_tgt() -> str:
14
  """
15
+ Get Ticket Granting Ticket (TGT) from UMLS API key.
16
  """
17
+ params = {"apikey": UMLS_API_KEY}
18
+ r = requests.post(UMLS_AUTH_ENDPOINT, data=params)
19
  r.raise_for_status()
20
+ # Extract TGT from HTML form action
21
+ tgt_url = r.text.split('action="')[1].split('"')[0]
22
+ return tgt_url
 
23
 
24
+ def get_service_ticket(tgt_url: str) -> str:
25
  """
26
+ Get a one-time Service Ticket (ST) for API calls.
27
  """
28
+ params = {"service": "http://umlsks.nlm.nih.gov"}
29
+ r = requests.post(tgt_url, data=params)
30
  r.raise_for_status()
31
  return r.text
32
 
33
+ # -------------------------
34
+ # SEARCH FUNCTIONS
35
+ # -------------------------
36
+ def search_umls(term: str, max_results: int = 10) -> List[Dict]:
37
  """
38
+ Search UMLS for a medical concept by term and return CUIs, preferred names, and semantic types.
39
  """
40
  tgt = get_tgt()
41
+ st = get_service_ticket(tgt)
42
+ params = {
43
+ "string": term,
44
+ "ticket": st,
45
+ "pageSize": max_results
46
+ }
47
  r = requests.get(f"{UMLS_BASE}/search/current", params=params)
48
  r.raise_for_status()
49
+ data = r.json()
50
+
51
+ results = []
52
+ for item in data.get("result", {}).get("results", []):
53
+ results.append({
54
+ "ui": item.get("ui"), # CUI
55
  "name": item.get("name"),
56
  "rootSource": item.get("rootSource")
57
+ })
58
+ return results
 
 
59
 
60
+ def get_cui_details(cui: str) -> Dict:
61
  """
62
+ Retrieve details for a specific CUI.
 
63
  """
64
  tgt = get_tgt()
65
+ st = get_service_ticket(tgt)
66
+ params = {"ticket": st}
67
+ r = requests.get(f"{UMLS_BASE}/content/current/CUI/{cui}", params=params)
68
  r.raise_for_status()
69
+ return r.json()
70
 
71
+ def get_cui_relations(cui: str) -> List[Dict]:
 
72
  """
73
+ Get relationships for a CUI (e.g., associated diseases, drugs, symptoms).
74
  """
75
  tgt = get_tgt()
76
+ st = get_service_ticket(tgt)
77
+ params = {"ticket": st}
78
+ r = requests.get(f"{UMLS_BASE}/content/current/CUI/{cui}/relations", params=params)
79
  r.raise_for_status()
80
+ data = r.json()
 
81
 
82
+ relations = []
83
+ for rel in data.get("result", []):
84
+ relations.append({
85
+ "relationLabel": rel.get("relationLabel"),
86
+ "relatedId": rel.get("relatedId"),
87
+ "relatedName": rel.get("relatedIdName")
88
+ })
89
+ return relations