mgbam commited on
Commit
5d5509c
·
verified ·
1 Parent(s): 3cc71e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -32
app.py CHANGED
@@ -30,7 +30,7 @@ API_ENDPOINTS = {
30
  "who_drugs": "https://health-products.canada.ca/api/drug/product",
31
  "fda_drug_approval": "https://api.fda.gov/drug/label.json",
32
  "faers_adverse_events": "https://api.fda.gov/drug/event.json",
33
- # PharmGKB endpoints expect a PharmGKB accession (e.g., PA1234)
34
  "pharmgkb_variant_clinical_annotations": "https://api.pharmgkb.org/v1/data/variant/{}/clinicalAnnotations",
35
  "pharmgkb_gene": "https://api.pharmgkb.org/v1/data/gene/{}", # expects PharmGKB accession
36
  "pharmgkb_gene_variants": "https://api.pharmgkb.org/v1/data/gene/{}/variants",
@@ -43,7 +43,7 @@ API_ENDPOINTS = {
43
  # -----------------------------------
44
  OPENAI_API_KEY = st.secrets.get("OPENAI_API_KEY")
45
  BIOPORTAL_API_KEY = st.secrets.get("BIOPORTAL_API_KEY")
46
- PUB_EMAIL = st.secrets.get("PUB_EMAIL")
47
  OPENFDA_KEY = st.secrets.get("OPENFDA_KEY")
48
 
49
  if not PUB_EMAIL:
@@ -62,7 +62,7 @@ from openai import OpenAI
62
  client = OpenAI(api_key=OPENAI_API_KEY)
63
 
64
  def generate_content(prompt: str) -> str:
65
- """Generate content using GPT-4 via the new OpenAI SDK."""
66
  try:
67
  completion = client.chat.completions.create(
68
  model="gpt-4",
@@ -99,7 +99,7 @@ def _get_pubchem_smiles(drug_name: str) -> Optional[str]:
99
  """Retrieves a drug's SMILES string from PubChem."""
100
  url = API_ENDPOINTS["pubchem"].format(drug_name)
101
  data = _query_api(url)
102
- if data and "PC_Compounds" in data and len(data["PC_Compounds"]) > 0:
103
  for prop in data["PC_Compounds"][0].get("props", []):
104
  if prop.get("name") == "Canonical SMILES":
105
  return prop["value"]["sval"]
@@ -119,23 +119,21 @@ def _draw_molecule(smiles: str) -> Optional[Any]:
119
  logging.error(f"Molecule drawing error: {e}")
120
  return None
121
 
122
- def _get_clinical_trials(query: str, email: Optional[str] = PUB_EMAIL) -> Optional[Dict]:
123
- """Queries clinicaltrials.gov with a search term."""
124
- if not email:
125
- st.error("PubMed email not configured.")
126
- return None
127
- if query.upper().startswith("NCT") and query[3:].isdigit():
128
- params = {"id": query, "fmt": "json"}
129
- else:
130
- params = {"term": query, "retmax": 10, "retmode": "json", "email": email}
131
- return _query_api(API_ENDPOINTS["clinical_trials"], params)
 
132
 
133
- def _get_pubmed(query: str, email: Optional[str] = PUB_EMAIL) -> Optional[Dict]:
134
  """Queries PubMed using E-utilities."""
135
- if not email:
136
- st.error("PubMed email not configured.")
137
- return None
138
- params = {"db": "pubmed", "term": query, "retmax": 10, "retmode": "json", "email": email}
139
  return _query_api(API_ENDPOINTS["pubmed"], params)
140
 
141
  def _get_fda_approval(drug_name: str, api_key: Optional[str] = OPENFDA_KEY) -> Optional[Dict]:
@@ -170,8 +168,8 @@ def _get_pharmgkb_clinical_annotations(variant_id: str) -> Optional[Dict]:
170
 
171
  def _get_pharmgkb_variants_for_gene(pharmgkb_gene_id: str) -> Optional[List[str]]:
172
  """
173
- Retrieves variant IDs for a gene using the PharmGKB accession.
174
- The input must start with "PA". If not, a warning is issued.
175
  """
176
  if not pharmgkb_gene_id.startswith("PA"):
177
  st.warning("Please provide a valid PharmGKB accession ID for the gene (e.g., PA1234).")
@@ -184,10 +182,7 @@ def _get_pharmgkb_variants_for_gene(pharmgkb_gene_id: str) -> Optional[List[str]
184
  return None
185
 
186
  def get_pharmgkb_gene_data(pharmgkb_gene_id: str) -> Optional[Dict]:
187
- """
188
- Retrieves PharmGKB gene data using a PharmGKB accession.
189
- If the gene identifier does not start with "PA", a warning is issued.
190
- """
191
  if not pharmgkb_gene_id.startswith("PA"):
192
  st.warning("Please enter a valid PharmGKB gene accession ID (e.g., PA1234).")
193
  return None
@@ -199,7 +194,7 @@ def get_pharmgkb_gene_data(pharmgkb_gene_id: str) -> Optional[Dict]:
199
  return None
200
 
201
  def scrape_ema_drug_info(drug_name: str) -> Optional[Dict]:
202
- """Scrapes EMA website for drug information using a browser-like header."""
203
  try:
204
  search_url = f"https://www.ema.europa.eu/en/search?text={drug_name.replace(' ', '+')}&type=Product"
205
  headers = {
@@ -234,7 +229,7 @@ def scrape_ema_drug_info(drug_name: str) -> Optional[Dict]:
234
  return None
235
 
236
  def _get_dailymed_label(drug_name: str) -> Optional[Dict]:
237
- """Retrieves DailyMed label info; handles missing 'url' key gracefully."""
238
  try:
239
  params = {"drug_name": drug_name, "page": 1, "pagesize": 1}
240
  data = _query_api(API_ENDPOINTS["dailymed"], params)
@@ -474,7 +469,7 @@ with tabs[2]:
474
  if st.button("Analyze Compound"):
475
  with st.spinner("Querying PubChem..."):
476
  smiles = None
477
- # If the input is already a valid SMILES, use it; otherwise query PubChem
478
  if Chem.MolFromSmiles(compound_input):
479
  smiles = compound_input
480
  else:
@@ -484,7 +479,7 @@ with tabs[2]:
484
  if img:
485
  st.image(img, caption="2D Structure")
486
  else:
487
- st.error("Compound structure not found in databases.")
488
 
489
  pubchem_data = _query_api(API_ENDPOINTS["pubchem"].format(compound_input))
490
  if pubchem_data and pubchem_data.get("PC_Compounds"):
@@ -515,7 +510,7 @@ with tabs[3]:
515
  ema_info = scrape_ema_drug_info(drug_name)
516
  ema_status = ema_info.get("EMA Approval Status") if ema_info else "Not Available"
517
 
518
- # WHO Data from Canada Health Products API (this endpoint may return 404)
519
  who = _query_api(API_ENDPOINTS["who_drugs"], params={"name": drug_name})
520
  who_status = "Yes" if who else "No"
521
 
@@ -630,7 +625,6 @@ with tabs[5]:
630
  st.pyplot(fig)
631
 
632
  st.subheader("Gene-Variant-Drug Network (Sample)")
633
- # Sample network demonstration
634
  sample_gene = "CYP2C19"
635
  sample_variants = ["rs4244285", "rs12248560"]
636
  sample_annotations = {
@@ -641,4 +635,17 @@ with tabs[5]:
641
  network_fig = _create_variant_network(sample_gene, sample_variants, sample_annotations)
642
  st.plotly_chart(network_fig, use_container_width=True)
643
  except Exception as e:
644
- st.error(f"Error generating network graph: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  "who_drugs": "https://health-products.canada.ca/api/drug/product",
31
  "fda_drug_approval": "https://api.fda.gov/drug/label.json",
32
  "faers_adverse_events": "https://api.fda.gov/drug/event.json",
33
+ # PharmGKB endpoints require a PharmGKB accession (e.g., PA1234)
34
  "pharmgkb_variant_clinical_annotations": "https://api.pharmgkb.org/v1/data/variant/{}/clinicalAnnotations",
35
  "pharmgkb_gene": "https://api.pharmgkb.org/v1/data/gene/{}", # expects PharmGKB accession
36
  "pharmgkb_gene_variants": "https://api.pharmgkb.org/v1/data/gene/{}/variants",
 
43
  # -----------------------------------
44
  OPENAI_API_KEY = st.secrets.get("OPENAI_API_KEY")
45
  BIOPORTAL_API_KEY = st.secrets.get("BIOPORTAL_API_KEY")
46
+ PUB_EMAIL = st.secrets.get("PUB_EMAIL") # Not used in clinical trials anymore.
47
  OPENFDA_KEY = st.secrets.get("OPENFDA_KEY")
48
 
49
  if not PUB_EMAIL:
 
62
  client = OpenAI(api_key=OPENAI_API_KEY)
63
 
64
  def generate_content(prompt: str) -> str:
65
+ """Generate content using GPT-4 via the latest OpenAI SDK."""
66
  try:
67
  completion = client.chat.completions.create(
68
  model="gpt-4",
 
99
  """Retrieves a drug's SMILES string from PubChem."""
100
  url = API_ENDPOINTS["pubchem"].format(drug_name)
101
  data = _query_api(url)
102
+ if data and "PC_Compounds" in data and data["PC_Compounds"]:
103
  for prop in data["PC_Compounds"][0].get("props", []):
104
  if prop.get("name") == "Canonical SMILES":
105
  return prop["value"]["sval"]
 
119
  logging.error(f"Molecule drawing error: {e}")
120
  return None
121
 
122
+ def _get_clinical_trials(query: str) -> Optional[Dict]:
123
+ """Queries clinicaltrials.gov with a search term.
124
+ Note: the email parameter has been removed as it is not required."""
125
+ # Try using 'term' and if that fails, try 'query.term'
126
+ params = {"term": query, "retmax": 10, "retmode": "json"}
127
+ data = _query_api(API_ENDPOINTS["clinical_trials"], params)
128
+ if not data:
129
+ # Fallback to alternative parameter name:
130
+ params = {"query.term": query, "retmax": 10, "retmode": "json"}
131
+ data = _query_api(API_ENDPOINTS["clinical_trials"], params)
132
+ return data
133
 
134
+ def _get_pubmed(query: str) -> Optional[Dict]:
135
  """Queries PubMed using E-utilities."""
136
+ params = {"db": "pubmed", "term": query, "retmax": 10, "retmode": "json", "email": PUB_EMAIL}
 
 
 
137
  return _query_api(API_ENDPOINTS["pubmed"], params)
138
 
139
  def _get_fda_approval(drug_name: str, api_key: Optional[str] = OPENFDA_KEY) -> Optional[Dict]:
 
168
 
169
  def _get_pharmgkb_variants_for_gene(pharmgkb_gene_id: str) -> Optional[List[str]]:
170
  """
171
+ Retrieves variant IDs for a gene using its PharmGKB accession.
172
+ If an invalid accession is provided (not starting with "PA"), a warning is issued.
173
  """
174
  if not pharmgkb_gene_id.startswith("PA"):
175
  st.warning("Please provide a valid PharmGKB accession ID for the gene (e.g., PA1234).")
 
182
  return None
183
 
184
  def get_pharmgkb_gene_data(pharmgkb_gene_id: str) -> Optional[Dict]:
185
+ """Retrieves PharmGKB gene data using a PharmGKB accession."""
 
 
 
186
  if not pharmgkb_gene_id.startswith("PA"):
187
  st.warning("Please enter a valid PharmGKB gene accession ID (e.g., PA1234).")
188
  return None
 
194
  return None
195
 
196
  def scrape_ema_drug_info(drug_name: str) -> Optional[Dict]:
197
+ """Scrapes the EMA website for drug information using a browser-like header."""
198
  try:
199
  search_url = f"https://www.ema.europa.eu/en/search?text={drug_name.replace(' ', '+')}&type=Product"
200
  headers = {
 
229
  return None
230
 
231
  def _get_dailymed_label(drug_name: str) -> Optional[Dict]:
232
+ """Retrieves DailyMed label info; if URL is missing, returns None."""
233
  try:
234
  params = {"drug_name": drug_name, "page": 1, "pagesize": 1}
235
  data = _query_api(API_ENDPOINTS["dailymed"], params)
 
469
  if st.button("Analyze Compound"):
470
  with st.spinner("Querying PubChem..."):
471
  smiles = None
472
+ # If the input is already a valid SMILES string, use it; otherwise, query PubChem.
473
  if Chem.MolFromSmiles(compound_input):
474
  smiles = compound_input
475
  else:
 
479
  if img:
480
  st.image(img, caption="2D Structure")
481
  else:
482
+ st.error("Compound structure not found in databases. Please provide a more specific compound name.")
483
 
484
  pubchem_data = _query_api(API_ENDPOINTS["pubchem"].format(compound_input))
485
  if pubchem_data and pubchem_data.get("PC_Compounds"):
 
510
  ema_info = scrape_ema_drug_info(drug_name)
511
  ema_status = ema_info.get("EMA Approval Status") if ema_info else "Not Available"
512
 
513
+ # WHO Data from Health Canada API fallback if not found
514
  who = _query_api(API_ENDPOINTS["who_drugs"], params={"name": drug_name})
515
  who_status = "Yes" if who else "No"
516
 
 
625
  st.pyplot(fig)
626
 
627
  st.subheader("Gene-Variant-Drug Network (Sample)")
 
628
  sample_gene = "CYP2C19"
629
  sample_variants = ["rs4244285", "rs12248560"]
630
  sample_annotations = {
 
635
  network_fig = _create_variant_network(sample_gene, sample_variants, sample_annotations)
636
  st.plotly_chart(network_fig, use_container_width=True)
637
  except Exception as e:
638
+ st.error(f"Error generating network graph: {e}")
639
+
640
+ # -----------------------------
641
+ # Sidebar Information
642
+ # -----------------------------
643
+ st.sidebar.header("About")
644
+ st.sidebar.info("""
645
+ **Pharma Research Expert Platform**
646
+
647
+ An integrated tool for drug discovery, clinical research, and regulatory affairs.
648
+
649
+ **Developed by:** Your Name
650
+ **Contact:** [[email protected]](mailto:[email protected])
651
+ """)