1-
2-
31from typing import Optional
42import logging
53from .variant_ontology import BaseNormalizer , NormalizationResult
64
75import requests
86
9- # how to use, you have thew following,
7+ # how to use, you have thew following,
108
119
1210logger = logging .getLogger (__name__ )
1311
12+
1413class DrugNormalizer (BaseNormalizer ):
1514 """Normalizes drug names, and connect to common ID's per use."""
1615
1716 def __init__ (self ):
1817 super ().__init__ ()
19-
20- self .register_handler (self .lookup_drug_pubchem )
21-
22-
2318
24- #TODO: insert logic to handle base generic instead of what we have
19+ self . register_handler ( self . lookup_drug_pubchem )
2520
21+ # TODO: insert logic to handle base generic instead of what we have
2622
2723 self .register_handler (self .lookup_drug_pharmgkb )
28- # register the pubchem first before I register the other.
24+ # register the pubchem first before I register the other.
25+
2926 def name (self ):
3027 return "Drug Normalizer"
3128
@@ -68,8 +65,8 @@ def lookup_drug_pubchem(self, raw: str) -> Optional[NormalizationResult]:
6865 metadata = {
6966 "cid" : cid ,
7067 "molecular_formula" : props .get ("MolecularFormula" ),
71- "canonical_smiles" : props .get ("CanonicalSMILES" )
72- }
68+ "canonical_smiles" : props .get ("CanonicalSMILES" ),
69+ },
7370 )
7471
7572 except requests .RequestException as exc :
@@ -78,6 +75,7 @@ def lookup_drug_pubchem(self, raw: str) -> Optional[NormalizationResult]:
7875 logger .warning ("Unexpected error for '%s': %s" , raw , exc )
7976
8077 return None
78+
8179 def get_generic_from_brand_pubchem (self , raw : str ) -> Optional [str ]:
8280 """
8381 Resolves a brand name to a generic (IUPAC) name using PubChem.
@@ -88,13 +86,12 @@ def get_generic_from_brand_pubchem(self, raw: str) -> Optional[str]:
8886 return result .normalized_output
8987 return None
9088
91-
9289 def lookup_drug_pharmgkb (self , raw : str ) -> Optional [NormalizationResult ]:
9390 """
9491 Lookup drug info from PharmGKB using its REST API.
9592 Returns all available metadata without filtering.
9693 """
97- query = raw .strip ().lower ()
94+ query = raw .strip ().lower ()
9895 if not query :
9996 logger .debug ("Empty drug input for PharmGKB lookup." )
10097 return None
@@ -121,15 +118,18 @@ def lookup_drug_pharmgkb(self, raw: str) -> Optional[NormalizationResult]:
121118 normalized_output = entry .get ("name" , raw ),
122119 entity_type = "drug" ,
123120 source = "PharmGKB" ,
124- metadata = entry # Store the entire returned dictionary
121+ metadata = entry , # Store the entire returned dictionary
125122 )
126123
127124 except requests .RequestException as exc :
128125 logger .warning ("PharmGKB request failed for '%s': %s" , raw , exc )
129126 except Exception as exc :
130- logger .warning ("Unexpected error during PharmGKB lookup for '%s': %s" , raw , exc )
127+ logger .warning (
128+ "Unexpected error during PharmGKB lookup for '%s': %s" , raw , exc
129+ )
131130
132131 return None
132+
133133 def lookup_drug_rxnorm (self , raw : str ) -> Optional [NormalizationResult ]:
134134 """
135135 Resolves a drug name (brand or generic) using the RxNorm API.
@@ -153,7 +153,9 @@ def lookup_drug_rxnorm(self, raw: str) -> Optional[NormalizationResult]:
153153 rxcui = rxcui_list [0 ]
154154
155155 # Step 2: Get related ingredient (generic) names from RxCUI
156- related_url = f"https://rxnav.nlm.nih.gov/REST/rxcui/{ rxcui } /related.json?tty=IN"
156+ related_url = (
157+ f"https://rxnav.nlm.nih.gov/REST/rxcui/{ rxcui } /related.json?tty=IN"
158+ )
157159 related_resp = requests .get (related_url , timeout = 5 )
158160 related_resp .raise_for_status ()
159161 related_data = related_resp .json ()
@@ -174,10 +176,7 @@ def lookup_drug_rxnorm(self, raw: str) -> Optional[NormalizationResult]:
174176 normalized_output = ingredients [0 ], # first generic match
175177 entity_type = "drug" ,
176178 source = "RxNorm" ,
177- metadata = {
178- "rxcui" : rxcui ,
179- "generic_candidates" : ingredients
180- }
179+ metadata = {"rxcui" : rxcui , "generic_candidates" : ingredients },
181180 )
182181
183182 except requests .RequestException as exc :
@@ -188,8 +187,6 @@ def lookup_drug_rxnorm(self, raw: str) -> Optional[NormalizationResult]:
188187 return None
189188
190189
191-
192-
193190def test_lookup_pubchem ():
194191 normalizer = DrugNormalizer ()
195192 drug = "Imatinib"
@@ -239,9 +236,8 @@ def test_lookup_pharmgkb():
239236
240237if __name__ == "__main__" :
241238 test_lookup_pubchem ()
242-
239+
243240 test_lookup_pharmgkb ()
244241 normalizer = DrugNormalizer ()
245242 result = normalizer .lookup_drug_rxnorm ("Gleevec" )
246243 print (result .normalized_output ) # → "imatinib"
247-
0 commit comments