mgbam commited on
Commit
758da30
·
verified ·
1 Parent(s): ea8c68b

Update genesis/api_clients/umls_api.py

Browse files
Files changed (1) hide show
  1. genesis/api_clients/umls_api.py +58 -42
genesis/api_clients/umls_api.py CHANGED
@@ -1,89 +1,105 @@
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
 
 
 
 
 
 
 
 
1
  # genesis/api_clients/umls_api.py
2
  import os
3
  import requests
4
+ from typing import Dict, List, Optional
5
 
6
+ UMLS_API_KEY = os.getenv("UMLS_API_KEY")
7
+ UMLS_BASE = "https://uts-ws.nlm.nih.gov"
8
+
9
+ if not UMLS_API_KEY:
10
+ raise EnvironmentError("Missing UMLS_API_KEY in environment variables.")
11
 
12
  # -------------------------
13
  # AUTHENTICATION
14
  # -------------------------
15
  def get_tgt() -> str:
16
  """
17
+ Get a Ticket Granting Ticket (TGT) from UMLS.
18
  """
19
+ r = requests.post(
20
+ f"{UMLS_BASE}/restful/isValidService",
21
+ data={"apikey": UMLS_API_KEY}
22
+ )
23
+ if r.status_code != 201:
24
+ raise Exception(f"Failed to get UMLS TGT: {r.text}")
25
+ return r.headers.get("location")
26
 
27
+ def get_service_ticket(tgt: str) -> str:
28
  """
29
+ Get a single-use Service Ticket from the TGT.
30
  """
31
+ r = requests.post(tgt, data={"service": "http://umlsks.nlm.nih.gov"})
 
32
  r.raise_for_status()
33
  return r.text
34
 
35
  # -------------------------
36
+ # CORE FUNCTIONS
37
  # -------------------------
38
+ def search_cui(term: str, page_size: int = 10) -> List[Dict]:
39
  """
40
+ Search for UMLS CUIs for a given term.
41
  """
42
  tgt = get_tgt()
43
+ ticket = get_service_ticket(tgt)
44
+
45
  params = {
46
  "string": term,
47
+ "ticket": ticket,
48
+ "pageSize": page_size
49
  }
50
+ r = requests.get(f"{UMLS_BASE}/rest/search/current", params=params)
51
  r.raise_for_status()
52
  data = r.json()
53
 
54
  results = []
55
+ for result in data.get("result", {}).get("results", []):
56
  results.append({
57
+ "ui": result.get("ui"),
58
+ "name": result.get("name"),
59
+ "rootSource": result.get("rootSource")
60
  })
61
  return results
62
 
63
  def get_cui_details(cui: str) -> Dict:
64
  """
65
+ Retrieve detailed information about a specific CUI.
66
  """
67
  tgt = get_tgt()
68
+ ticket = get_service_ticket(tgt)
69
+
70
+ params = {"ticket": ticket}
71
+ r = requests.get(f"{UMLS_BASE}/rest/content/current/CUI/{cui}", params=params)
72
  r.raise_for_status()
73
  return r.json()
74
 
75
+ def get_related_concepts(cui: str, relation_type: str = "RO") -> List[Dict]:
76
  """
77
+ Get related concepts for a given CUI.
78
+ relation_type: 'RO' (related other), 'RQ' (related and qualified), etc.
79
  """
80
  tgt = get_tgt()
81
+ ticket = get_service_ticket(tgt)
82
+
83
+ params = {"ticket": ticket}
84
+ r = requests.get(
85
+ f"{UMLS_BASE}/rest/content/current/CUI/{cui}/relations",
86
+ params=params
87
+ )
88
  r.raise_for_status()
89
  data = r.json()
90
 
91
+ related = []
92
  for rel in data.get("result", []):
93
+ if rel.get("relationLabel") == relation_type:
94
+ related.append({
95
+ "cui": rel.get("relatedIdName"),
96
+ "name": rel.get("relatedIdName"),
97
+ "relation": rel.get("relationLabel")
98
+ })
99
+ return related
100
+
101
+ def link_to_bioportal(cui: str) -> str:
102
+ """
103
+ Construct a BioPortal link for the given CUI.
104
+ """
105
+ return f"https://bioportal.bioontology.org/search?query={cui}"