mgbam commited on
Commit
2c00ea4
·
verified ·
1 Parent(s): 6409f04

Update genesis/api_clients/umls_api.py

Browse files
Files changed (1) hide show
  1. genesis/api_clients/umls_api.py +83 -62
genesis/api_clients/umls_api.py CHANGED
@@ -1,105 +1,126 @@
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}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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"
8
+ UMLS_BASE = "https://uts-ws.nlm.nih.gov/rest"
9
 
10
+ session = requests.Session()
 
11
 
12
  # -------------------------
13
+ # UMLS Authentication
14
  # -------------------------
15
+ def get_umls_ticket_granting_ticket() -> str:
16
  """
17
+ Get the Ticket Granting Ticket (TGT) for UMLS API authentication.
18
  """
19
+ if not UMLS_API_KEY:
20
+ raise ValueError("UMLS API key not found in environment variables.")
21
+
22
+ params = {"apikey": UMLS_API_KEY}
23
+ r = session.post(UMLS_AUTH_ENDPOINT, data=params)
24
+ r.raise_for_status()
25
+
26
+ # The TGT is returned in the Location header of the POST response
27
  return r.headers.get("location")
28
 
29
+ def get_umls_service_ticket(tgt: str) -> str:
30
  """
31
+ Use TGT to request a one-time Service Ticket (ST).
32
  """
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 UMLS Concepts
40
  # -------------------------
41
+ def search_umls(term: str, page_size: int = 5) -> List[Dict]:
42
  """
43
+ Search the UMLS Metathesaurus for a given term and return related CUIs.
44
  """
45
+ tgt = get_umls_ticket_granting_ticket()
46
+ st = get_umls_service_ticket(tgt)
47
 
48
  params = {
49
  "string": term,
50
+ "ticket": st,
51
  "pageSize": page_size
52
  }
53
+ r = session.get(f"{UMLS_BASE}/search/current", params=params)
54
  r.raise_for_status()
55
+
56
+ results = r.json().get("result", {}).get("results", [])
57
+ concepts = []
58
+ for res in results:
59
+ concepts.append({
60
+ "name": res.get("name"),
61
+ "cui": res.get("ui"),
62
+ "rootSource": res.get("rootSource")
63
  })
64
+ return concepts
65
 
66
+ # -------------------------
67
+ # Get UMLS Concept Details
68
+ # -------------------------
69
+ def get_concept_details(cui: str) -> Dict:
70
  """
71
+ Fetch full details for a UMLS concept (definitions, atoms, semantic types).
72
  """
73
+ tgt = get_umls_ticket_granting_ticket()
74
+ st = get_umls_service_ticket(tgt)
75
 
76
+ r = session.get(f"{UMLS_BASE}/content/current/CUI/{cui}", params={"ticket": st})
 
77
  r.raise_for_status()
78
+ return r.json().get("result", {})
79
 
80
+ # -------------------------
81
+ # Get Related Concepts
82
+ # -------------------------
83
+ def get_related_concepts(cui: str) -> List[Dict]:
84
  """
85
+ Fetch related concepts for a given CUI.
 
86
  """
87
+ tgt = get_umls_ticket_granting_ticket()
88
+ st = get_umls_service_ticket(tgt)
89
+
90
+ r = session.get(f"{UMLS_BASE}/content/current/CUI/{cui}/relations", params={"ticket": st})
 
 
 
 
91
  r.raise_for_status()
 
92
 
93
+ relations = r.json().get("result", [])
94
  related = []
95
+ for rel in relations:
96
+ related.append({
97
+ "relatedCUI": rel.get("relatedId"),
98
+ "relationLabel": rel.get("relationLabel"),
99
+ "relatedName": rel.get("relatedIdName")
100
+ })
 
101
  return related
102
 
103
+ # -------------------------
104
+ # Map Term to Related Network
105
+ # -------------------------
106
+ def umls_network(term: str) -> Dict:
107
  """
108
+ Build a semantic network for a term: CUI, details, and related concepts.
109
  """
110
+ concepts = search_umls(term)
111
+ network = []
112
+
113
+ for concept in concepts:
114
+ cui = concept["cui"]
115
+ details = get_concept_details(cui)
116
+ related = get_related_concepts(cui)
117
+ network.append({
118
+ "concept": concept,
119
+ "details": details,
120
+ "related": related
121
+ })
122
+
123
+ return {
124
+ "term": term,
125
+ "network": network
126
+ }