mgbam commited on
Commit
402d6f1
Β·
verified Β·
1 Parent(s): 5d65f21

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -38
app.py CHANGED
@@ -29,7 +29,7 @@ API_ENDPOINTS = {
29
  "pubmed": "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi",
30
  "fda_drug_approval": "https://api.fda.gov/drug/label.json",
31
  "faers_adverse_events": "https://api.fda.gov/drug/event.json",
32
- # PharmGKB endpoints (these require a PharmGKB accession such as "PA1234")
33
  "pharmgkb_variant_clinical_annotations": "https://api.pharmgkb.org/v1/data/variant/{}/clinicalAnnotations",
34
  "pharmgkb_gene": "https://api.pharmgkb.org/v1/data/gene/{}",
35
  "pharmgkb_gene_variants": "https://api.pharmgkb.org/v1/data/gene/{}/variants",
@@ -37,7 +37,7 @@ API_ENDPOINTS = {
37
  # RxNorm endpoints
38
  "rxnorm_rxcui": "https://rxnav.nlm.nih.gov/REST/rxcui.json",
39
  "rxnorm_properties": "https://rxnav.nlm.nih.gov/REST/rxcui/{}/properties.json",
40
- # RxClass endpoint (example)
41
  "rxclass_by_drug": "https://rxnav.nlm.nih.gov/REST/class/byDrugName.json"
42
  }
43
 
@@ -123,20 +123,19 @@ def _draw_molecule(smiles: str) -> Optional[Any]:
123
  return None
124
 
125
  def _get_pubchem_drug_details(drug_name: str) -> Optional[Dict[str, str]]:
126
- """Retrieves drug details such as molecular formula and IUPAC name from PubChem."""
127
  url = API_ENDPOINTS["pubchem"].format(drug_name)
128
  data = _query_api(url)
 
129
  if data and data.get("PC_Compounds"):
130
  compound = data["PC_Compounds"][0]
131
- details = {}
132
  for prop in compound.get("props", []):
133
  urn = prop.get("urn", {})
134
  if urn.get("label") == "Molecular Formula":
135
  details["Molecular Formula"] = prop["value"]["sval"]
136
- elif urn.get("name") in ["Preferred", "Systematic"]:
137
- # Use Preferred IUPAC name if available
138
  details["IUPAC Name"] = prop["value"]["sval"]
139
- elif prop.get("name") == "Canonical SMILES":
140
  details["Canonical SMILES"] = prop["value"]["sval"]
141
  return details
142
  return None
@@ -335,30 +334,65 @@ def get_rxclass_by_drug_name(drug_name: str) -> Optional[Dict]:
335
  return _query_api(url)
336
 
337
  # -----------------------------
338
- # New Function: PubChem Drug Details
339
  # -----------------------------
340
- def _get_pubchem_drug_details(drug_name: str) -> Optional[Dict[str, str]]:
341
- """Retrieves generic drug details (molecular formula, IUPAC name, and canonical SMILES) from PubChem."""
342
- url = API_ENDPOINTS["pubchem"].format(drug_name)
343
- data = _query_api(url)
344
- details = {}
345
- if data and data.get("PC_Compounds"):
346
- compound = data["PC_Compounds"][0]
347
- for prop in compound.get("props", []):
348
- urn = prop.get("urn", {})
349
- if urn.get("label") == "Molecular Formula":
350
- details["Molecular Formula"] = prop["value"]["sval"]
351
- if urn.get("name") == "Preferred":
352
- details["IUPAC Name"] = prop["value"]["sval"]
353
- if prop.get("name") == "Canonical SMILES":
354
- details["Canonical SMILES"] = prop["value"]["sval"]
355
- return details
356
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
 
358
  # -----------------------------
359
  # Streamlit App Layout and Tabs
360
  # -----------------------------
361
- # Define tabs including a new "Drug Data Integration" tab.
362
  tabs = st.tabs([
363
  "πŸ’Š Drug Development",
364
  "πŸ“Š Trial Analytics",
@@ -366,7 +400,8 @@ tabs = st.tabs([
366
  "πŸ“œ Regulatory Intelligence",
367
  "πŸ“š Literature Search",
368
  "πŸ“ˆ Dashboard",
369
- "πŸ§ͺ Drug Data Integration"
 
370
  ])
371
 
372
  # -----------------------------
@@ -505,7 +540,7 @@ with tabs[2]:
505
  # -----------------------------
506
  with tabs[3]:
507
  st.header("Global Regulatory Monitoring")
508
- st.markdown("**Note:** EMA, WHO, and DailyMed endpoints have been removed due to persistent errors. Instead, we provide FDA data and generic drug details (formula, IUPAC name, structure) from PubChem.")
509
  drug_name = st.text_input("Drug Product:", placeholder="Enter generic or brand name")
510
 
511
  if st.button("Generate Regulatory Report"):
@@ -521,27 +556,27 @@ with tabs[3]:
521
  if pubchem_details:
522
  formula = pubchem_details.get("Molecular Formula", "N/A")
523
  iupac = pubchem_details.get("IUPAC Name", "N/A")
524
- smiles = pubchem_details.get("Canonical SMILES", "N/A")
525
  else:
526
- formula = iupac = smiles = "Not Available"
527
 
528
- st.subheader("Regulatory Status")
529
  col1, col2 = st.columns(2)
530
  with col1:
531
  st.markdown("**FDA Status**")
532
  st.write(fda_status)
533
  with col2:
534
- st.markdown("**Generic/Formula Details (PubChem)**")
535
  st.write(f"**Molecular Formula:** {formula}")
536
  st.write(f"**IUPAC Name:** {iupac}")
537
- st.write(f"**Canonical SMILES:** {smiles}")
538
 
539
  regulatory_content = (
540
- f"### Regulatory Report\n\n"
541
  f"**FDA Status:** {fda_status}\n\n"
542
  f"**Molecular Formula:** {formula}\n\n"
543
  f"**IUPAC Name:** {iupac}\n\n"
544
- f"**Canonical SMILES:** {smiles}\n"
545
  )
546
  with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
547
  report_file = _save_pdf_report(regulatory_content, tmp_file.name)
@@ -595,8 +630,6 @@ with tabs[5]:
595
 
596
  # Placeholder KPI counts (replace with real aggregated data if available)
597
  fda_count = 5000 # Example value
598
- ema_count = 3000 # Example value (not used now)
599
- who_count = 1500 # Example value (not used now)
600
  trials_count = 12000 # Example value
601
  pub_count = 250000 # Example value
602
 
@@ -666,7 +699,7 @@ with tabs[6]:
666
  else:
667
  st.write("No RxClass data found for the given drug.")
668
 
669
- # Additionally, show generic drug details from PubChem
670
  pubchem_details = _get_pubchem_drug_details(drug_query)
671
  st.subheader("PubChem Drug Details")
672
  if pubchem_details:
@@ -676,4 +709,16 @@ with tabs[6]:
676
  else:
677
  st.write("No PubChem details found for the given drug.")
678
 
 
 
 
 
 
 
 
 
 
 
 
 
679
 
 
29
  "pubmed": "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi",
30
  "fda_drug_approval": "https://api.fda.gov/drug/label.json",
31
  "faers_adverse_events": "https://api.fda.gov/drug/event.json",
32
+ # PharmGKB endpoints (expecting a PharmGKB accession, e.g. PA1234)
33
  "pharmgkb_variant_clinical_annotations": "https://api.pharmgkb.org/v1/data/variant/{}/clinicalAnnotations",
34
  "pharmgkb_gene": "https://api.pharmgkb.org/v1/data/gene/{}",
35
  "pharmgkb_gene_variants": "https://api.pharmgkb.org/v1/data/gene/{}/variants",
 
37
  # RxNorm endpoints
38
  "rxnorm_rxcui": "https://rxnav.nlm.nih.gov/REST/rxcui.json",
39
  "rxnorm_properties": "https://rxnav.nlm.nih.gov/REST/rxcui/{}/properties.json",
40
+ # RxClass endpoint
41
  "rxclass_by_drug": "https://rxnav.nlm.nih.gov/REST/class/byDrugName.json"
42
  }
43
 
 
123
  return None
124
 
125
  def _get_pubchem_drug_details(drug_name: str) -> Optional[Dict[str, str]]:
126
+ """Retrieves generic drug details (molecular formula, IUPAC name, and canonical SMILES) from PubChem."""
127
  url = API_ENDPOINTS["pubchem"].format(drug_name)
128
  data = _query_api(url)
129
+ details = {}
130
  if data and data.get("PC_Compounds"):
131
  compound = data["PC_Compounds"][0]
 
132
  for prop in compound.get("props", []):
133
  urn = prop.get("urn", {})
134
  if urn.get("label") == "Molecular Formula":
135
  details["Molecular Formula"] = prop["value"]["sval"]
136
+ if urn.get("name") == "Preferred":
 
137
  details["IUPAC Name"] = prop["value"]["sval"]
138
+ if prop.get("name") == "Canonical SMILES":
139
  details["Canonical SMILES"] = prop["value"]["sval"]
140
  return details
141
  return None
 
334
  return _query_api(url)
335
 
336
  # -----------------------------
337
+ # New Function: Generate AI Insights for a Drug
338
  # -----------------------------
339
+ def generate_drug_insights(drug_name: str) -> str:
340
+ """Gathers FDA, PubChem, RxNorm, and RxClass data for a drug and uses GPT‑4 to generate innovative insights."""
341
+ # FDA Data
342
+ fda_info = _get_fda_approval(drug_name)
343
+ fda_status = "Not Approved"
344
+ if fda_info and fda_info.get("openfda", {}).get("brand_name"):
345
+ fda_status = ", ".join(fda_info["openfda"]["brand_name"])
346
+
347
+ # PubChem Details
348
+ pubchem_details = _get_pubchem_drug_details(drug_name)
349
+ if pubchem_details:
350
+ formula = pubchem_details.get("Molecular Formula", "N/A")
351
+ iupac = pubchem_details.get("IUPAC Name", "N/A")
352
+ canonical_smiles = pubchem_details.get("Canonical SMILES", "N/A")
353
+ else:
354
+ formula = iupac = canonical_smiles = "Not Available"
355
+
356
+ # RxNorm Data
357
+ rxnorm_id = get_rxnorm_rxcui(drug_name)
358
+ if rxnorm_id:
359
+ rx_properties = get_rxnorm_properties(rxnorm_id)
360
+ rxnorm_info = f"RxCUI: {rxnorm_id}. Properties: {rx_properties}"
361
+ else:
362
+ rxnorm_info = "No RxNorm data available."
363
+
364
+ # RxClass Data
365
+ rxclass_data = get_rxclass_by_drug_name(drug_name)
366
+ if rxclass_data and rxclass_data.get("classMember"):
367
+ rxclass_info = f"RxClass: {rxclass_data}"
368
+ else:
369
+ rxclass_info = "No RxClass data available."
370
+
371
+ # Construct prompt for GPT‑4 with all the gathered data
372
+ prompt = (
373
+ f"Drug Analysis Report for '{drug_name}':\n\n"
374
+ f"**FDA Approval Status:** {fda_status}\n\n"
375
+ f"**PubChem Details:**\n"
376
+ f" - Molecular Formula: {formula}\n"
377
+ f" - IUPAC Name: {iupac}\n"
378
+ f" - Canonical SMILES: {canonical_smiles}\n\n"
379
+ f"**RxNorm Data:** {rxnorm_info}\n\n"
380
+ f"**RxClass Data:** {rxclass_info}\n\n"
381
+ f"As an advanced pharmacogenomics researcher and AI expert, please provide an innovative and comprehensive analysis of "
382
+ f"the drug '{drug_name}'. In your response, include:\n"
383
+ f"- Pharmacogenomic considerations\n"
384
+ f"- Potential repurposing opportunities\n"
385
+ f"- Regulatory insights and challenges\n"
386
+ f"- Suggestions for further research and data integration\n\n"
387
+ f"Present your answer in a clear, bullet-point format and feel free to add any novel ideas."
388
+ )
389
+
390
+ insights = generate_content(prompt)
391
+ return insights
392
 
393
  # -----------------------------
394
  # Streamlit App Layout and Tabs
395
  # -----------------------------
 
396
  tabs = st.tabs([
397
  "πŸ’Š Drug Development",
398
  "πŸ“Š Trial Analytics",
 
400
  "πŸ“œ Regulatory Intelligence",
401
  "πŸ“š Literature Search",
402
  "πŸ“ˆ Dashboard",
403
+ "πŸ§ͺ Drug Data Integration",
404
+ "πŸ€– AI Insights"
405
  ])
406
 
407
  # -----------------------------
 
540
  # -----------------------------
541
  with tabs[3]:
542
  st.header("Global Regulatory Monitoring")
543
+ st.markdown("**Note:** Due to persistent issues with EMA, WHO, and DailyMed APIs, this section now focuses on FDA data and generic drug details from PubChem.")
544
  drug_name = st.text_input("Drug Product:", placeholder="Enter generic or brand name")
545
 
546
  if st.button("Generate Regulatory Report"):
 
556
  if pubchem_details:
557
  formula = pubchem_details.get("Molecular Formula", "N/A")
558
  iupac = pubchem_details.get("IUPAC Name", "N/A")
559
+ canonical_smiles = pubchem_details.get("Canonical SMILES", "N/A")
560
  else:
561
+ formula = iupac = canonical_smiles = "Not Available"
562
 
563
+ st.subheader("Regulatory Status & Drug Details")
564
  col1, col2 = st.columns(2)
565
  with col1:
566
  st.markdown("**FDA Status**")
567
  st.write(fda_status)
568
  with col2:
569
+ st.markdown("**Drug Details (PubChem)**")
570
  st.write(f"**Molecular Formula:** {formula}")
571
  st.write(f"**IUPAC Name:** {iupac}")
572
+ st.write(f"**Canonical SMILES:** {canonical_smiles}")
573
 
574
  regulatory_content = (
575
+ f"### Regulatory Report for {drug_name}\n\n"
576
  f"**FDA Status:** {fda_status}\n\n"
577
  f"**Molecular Formula:** {formula}\n\n"
578
  f"**IUPAC Name:** {iupac}\n\n"
579
+ f"**Canonical SMILES:** {canonical_smiles}\n"
580
  )
581
  with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
582
  report_file = _save_pdf_report(regulatory_content, tmp_file.name)
 
630
 
631
  # Placeholder KPI counts (replace with real aggregated data if available)
632
  fda_count = 5000 # Example value
 
 
633
  trials_count = 12000 # Example value
634
  pub_count = 250000 # Example value
635
 
 
699
  else:
700
  st.write("No RxClass data found for the given drug.")
701
 
702
+ # PubChem Drug Details for generic information
703
  pubchem_details = _get_pubchem_drug_details(drug_query)
704
  st.subheader("PubChem Drug Details")
705
  if pubchem_details:
 
709
  else:
710
  st.write("No PubChem details found for the given drug.")
711
 
712
+ # -----------------------------
713
+ # Tab 8: AI Insights
714
+ # -----------------------------
715
+ with tabs[7]:
716
+ st.header("πŸ€– AI Insights")
717
+ ai_drug_query = st.text_input("Enter Drug Name for AI-Driven Analysis:", placeholder="e.g., aspirin")
718
+ if st.button("Generate AI Insights"):
719
+ with st.spinner("Generating AI insights..."):
720
+ insights = generate_drug_insights(ai_drug_query)
721
+ st.subheader("AI-Driven Drug Analysis")
722
+ st.markdown(insights)
723
+
724