mgbam commited on
Commit
40a1d7a
Β·
verified Β·
1 Parent(s): afe3c44

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -73
app.py CHANGED
@@ -2,8 +2,6 @@
2
 
3
  import os
4
  import streamlit as st
5
- from fastapi import FastAPI
6
- from fastapi.middleware.cors import CORSMiddleware
7
  import asyncio
8
  from pathlib import Path
9
  import pandas as pd
@@ -20,27 +18,15 @@ from streamlit_agraph import agraph, Node, Edge, Config
20
  ROOT = Path(__file__).parent
21
  LOGO = ROOT / "assets" / "logo.png"
22
 
23
- api = FastAPI(
24
- title="MedGenesis MCP Server",
25
- version="2.0.0",
26
- description="MedGenesis AI – Unified Intelligence from PubMed, ArXiv, OpenFDA, UMLS, GPT-4o"
27
- )
28
- api.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"])
29
-
30
- @api.post("/unified_search", response_model=UnifiedSearchResult)
31
- async def unified_search_endpoint(data: UnifiedSearchInput):
32
- return await orchestrate_search(data.query)
33
-
34
- @api.post("/ask_ai")
35
- async def ask_ai_endpoint(question: str, context: str = ""):
36
- return await answer_ai_question(question, context)
37
-
38
  def generate_pdf(papers):
39
- pdf = FPDF(); pdf.add_page(); pdf.set_font("Arial", size=12)
 
 
40
  pdf.cell(200, 10, "MedGenesis AI - Search Results", ln=True, align="C")
41
  pdf.ln(10)
42
  for i, p in enumerate(papers, 1):
43
- pdf.set_font("Arial", "B", 12); pdf.multi_cell(0, 10, f"{i}. {p['title']}")
 
44
  pdf.set_font("Arial", "", 10)
45
  pdf.multi_cell(0, 8, f"Authors: {p['authors']}\nLink: {p['link']}\nSummary: {p['summary']}\n")
46
  pdf.ln(2)
@@ -49,21 +35,17 @@ def generate_pdf(papers):
49
  def render_ui():
50
  st.set_page_config(page_title="MedGenesis AI", layout="wide")
51
 
52
- # Sidebar workspace
53
  with st.sidebar:
54
  st.header("πŸ—‚οΈ Workspace")
55
- ws = get_workspace()
56
- if ws:
57
- for i, item in enumerate(ws, 1):
58
- with st.expander(f"{i}. {item['query']}"):
59
- st.write("**AI Summary:**", item["result"]["ai_summary"])
60
- st.write("**Top Paper:**", item["result"]["papers"][0]["title"] if item["result"]["papers"] else "None")
61
- df = pd.DataFrame(item["result"]["papers"])
62
- st.download_button("πŸ“₯ CSV", df.to_csv(index=False), f"query_{i}.csv", "text/csv")
63
- else:
64
- st.info("Run & save searches here.")
65
-
66
- # Header
67
  col1, col2 = st.columns([0.15, 0.85])
68
  with col1:
69
  if LOGO.exists():
@@ -73,85 +55,69 @@ def render_ui():
73
  st.caption("Built by Oluwafemi Idiakhoa β€’ Hugging Face Spaces")
74
 
75
  st.markdown("---")
76
- query = st.text_input("πŸ” Enter biomedical research question:", placeholder="e.g. Glioblastoma CRISPR treatments")
77
 
78
  results = None
79
  if st.button("Run Search πŸš€"):
80
- with st.spinner("Fetching & synthesizing..."):
81
  results = asyncio.run(orchestrate_search(query))
82
- st.success("βœ… Search complete")
83
 
84
  if results:
85
  tabs = st.tabs(["πŸ“ Results", "πŸ—ΊοΈ Knowledge Graph", "πŸ“Š Visualizations"])
86
 
87
- # Tab 1: Results
88
  with tabs[0]:
89
- st.header("πŸ“š Top Papers")
90
  for i, p in enumerate(results["papers"], 1):
91
- st.markdown(f"**{i}. [{p['title']}]({p['link']})** \n*{p['authors']}* ({p['source']})")
92
  st.markdown(f"<div style='color:gray'>{p['summary']}</div>", unsafe_allow_html=True)
93
-
94
  if st.button("Save to Workspace"):
95
  save_query(query, results); st.success("Saved!")
96
-
97
  df = pd.DataFrame(results["papers"])
98
- st.download_button("πŸ“₯ Download CSV", df.to_csv(index=False), "results.csv", "text/csv")
99
  pdf = generate_pdf(results["papers"])
100
- st.download_button("πŸ“„ Download PDF", pdf, "results.pdf", "application/pdf")
101
-
102
  st.subheader("🧠 UMLS Concepts")
103
  for c in results["umls"]:
104
  if c.get("cui"):
105
- st.markdown(f"- **{c['name']}** (CUI: `{c['cui']}`): {c.get('definition','No definition')}")
106
-
107
- st.subheader("πŸ’Š Drug Safety (OpenFDA)")
108
  for d in results["drug_safety"]:
109
  st.json(d)
110
-
111
  st.subheader("πŸ€– AI Summary")
112
  st.info(results["ai_summary"])
113
 
114
- # Tab 2: Knowledge Graph with Search & Highlight
115
  with tabs[1]:
116
- st.header("πŸ—ΊοΈ Knowledge Graph Explorer")
117
- search_term = st.text_input("πŸ”Ž Highlight nodes containing:", value="")
118
  try:
119
  nodes, edges, config = build_agraph(results["papers"], results["umls"], results["drug_safety"])
120
- # Highlight logic
121
- if search_term.strip():
122
- pattern = re.compile(re.escape(search_term), re.IGNORECASE)
123
  for node in nodes:
124
- if pattern.search(node.label) or (hasattr(node, "tooltip") and pattern.search(getattr(node, "tooltip", ""))):
125
- node.color = "#f1c40f"
126
- node.size = max(node.size, 30)
127
  else:
128
  node.color = "#ddd"
129
  agraph(nodes=nodes, edges=edges, config=config)
130
  except Exception as e:
131
- st.warning("Knowledge graph unavailable: " + str(e))
132
 
133
- # Tab 3: Visualizations
134
  with tabs[2]:
135
- pub_years = [p["published"] for p in results["papers"] if p.get("published")]
136
- if pub_years:
137
- fig = px.histogram(pub_years, nbins=10, title="Publication Year Distribution")
138
- st.plotly_chart(fig)
139
 
140
- # Follow-up Q&A
141
  st.markdown("---")
142
- st.subheader("πŸ’¬ Ask Follow-up AI Question")
143
- follow_up = st.text_input("Based on above:", placeholder="e.g. Most promising therapy?")
144
  if st.button("Ask AI"):
145
  with st.spinner("Thinking..."):
146
- ai_ans = asyncio.run(answer_ai_question(follow_up, context=query))
147
- st.write(ai_ans.get("answer", ai_ans))
148
 
149
  st.markdown("---")
150
- st.caption("✨ Built by Oluwafemi Idiakhoa β€’ Powered by FastAPI, Streamlit, OpenAI, UMLS, OpenFDA, NCBI")
151
 
152
  if __name__ == "__main__":
153
- import sys
154
- if "runserver" in sys.argv:
155
- import uvicorn; uvicorn.run(api, host="0.0.0.0", port=7860)
156
- else:
157
- render_ui()
 
2
 
3
  import os
4
  import streamlit as st
 
 
5
  import asyncio
6
  from pathlib import Path
7
  import pandas as pd
 
18
  ROOT = Path(__file__).parent
19
  LOGO = ROOT / "assets" / "logo.png"
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  def generate_pdf(papers):
22
+ pdf = FPDF()
23
+ pdf.add_page()
24
+ pdf.set_font("Arial", size=12)
25
  pdf.cell(200, 10, "MedGenesis AI - Search Results", ln=True, align="C")
26
  pdf.ln(10)
27
  for i, p in enumerate(papers, 1):
28
+ pdf.set_font("Arial", "B", 12)
29
+ pdf.multi_cell(0, 10, f"{i}. {p['title']}")
30
  pdf.set_font("Arial", "", 10)
31
  pdf.multi_cell(0, 8, f"Authors: {p['authors']}\nLink: {p['link']}\nSummary: {p['summary']}\n")
32
  pdf.ln(2)
 
35
  def render_ui():
36
  st.set_page_config(page_title="MedGenesis AI", layout="wide")
37
 
 
38
  with st.sidebar:
39
  st.header("πŸ—‚οΈ Workspace")
40
+ for i, item in enumerate(get_workspace(), 1):
41
+ with st.expander(f"{i}. {item['query']}"):
42
+ st.write("**AI Summary:**", item["result"]["ai_summary"])
43
+ st.write("**Top Paper:**", item["result"]["papers"][0]["title"] if item["result"]["papers"] else "None")
44
+ df = pd.DataFrame(item["result"]["papers"])
45
+ st.download_button("πŸ“₯ CSV", df.to_csv(index=False), f"workspace_{i}.csv", "text/csv")
46
+ if not get_workspace():
47
+ st.info("Run and save searches here.")
48
+
 
 
 
49
  col1, col2 = st.columns([0.15, 0.85])
50
  with col1:
51
  if LOGO.exists():
 
55
  st.caption("Built by Oluwafemi Idiakhoa β€’ Hugging Face Spaces")
56
 
57
  st.markdown("---")
58
+ query = st.text_input("πŸ” Enter research question:", placeholder="e.g. CRISPR treatments for glioblastoma")
59
 
60
  results = None
61
  if st.button("Run Search πŸš€"):
62
+ with st.spinner("Analyzing..."):
63
  results = asyncio.run(orchestrate_search(query))
64
+ st.success("Search complete")
65
 
66
  if results:
67
  tabs = st.tabs(["πŸ“ Results", "πŸ—ΊοΈ Knowledge Graph", "πŸ“Š Visualizations"])
68
 
 
69
  with tabs[0]:
70
+ st.header("πŸ“š Papers")
71
  for i, p in enumerate(results["papers"], 1):
72
+ st.markdown(f"**{i}. [{p['title']}]({p['link']})** *{p['authors']}*")
73
  st.markdown(f"<div style='color:gray'>{p['summary']}</div>", unsafe_allow_html=True)
 
74
  if st.button("Save to Workspace"):
75
  save_query(query, results); st.success("Saved!")
 
76
  df = pd.DataFrame(results["papers"])
77
+ st.download_button("πŸ“₯ CSV", df.to_csv(index=False), "results.csv", "text/csv")
78
  pdf = generate_pdf(results["papers"])
79
+ st.download_button("πŸ“„ PDF", pdf, "results.pdf", "application/pdf")
 
80
  st.subheader("🧠 UMLS Concepts")
81
  for c in results["umls"]:
82
  if c.get("cui"):
83
+ st.markdown(f"- **{c['name']}** (CUI:{c['cui']}): {c.get('definition','')}")
84
+ st.subheader("πŸ’Š Drug Safety")
 
85
  for d in results["drug_safety"]:
86
  st.json(d)
 
87
  st.subheader("πŸ€– AI Summary")
88
  st.info(results["ai_summary"])
89
 
 
90
  with tabs[1]:
91
+ st.header("πŸ”Ž Knowledge Graph")
92
+ search_term = st.text_input("Highlight node containing text:", value="")
93
  try:
94
  nodes, edges, config = build_agraph(results["papers"], results["umls"], results["drug_safety"])
95
+ if search_term:
96
+ pat = re.compile(re.escape(search_term), re.IGNORECASE)
 
97
  for node in nodes:
98
+ if pat.search(node.label) or (hasattr(node, "tooltip") and pat.search(getattr(node, "tooltip", ""))):
99
+ node.color = "#f1c40f"; node.size = max(node.size, 30)
 
100
  else:
101
  node.color = "#ddd"
102
  agraph(nodes=nodes, edges=edges, config=config)
103
  except Exception as e:
104
+ st.warning("Graph unavailable: " + str(e))
105
 
 
106
  with tabs[2]:
107
+ years = [p["published"] for p in results["papers"] if p.get("published")]
108
+ if years:
109
+ st.plotly_chart(px.histogram(years, title="Pub Year"))
 
110
 
 
111
  st.markdown("---")
112
+ st.subheader("πŸ’¬ Ask AI a Follow-up")
113
+ fq = st.text_input("Ask based on above:", "")
114
  if st.button("Ask AI"):
115
  with st.spinner("Thinking..."):
116
+ ans = asyncio.run(answer_ai_question(fq, context=query))
117
+ st.write(ans.get("answer", ans))
118
 
119
  st.markdown("---")
120
+ st.caption("✨ Built by Oluwafemi Idiakhoa β€’ Powered by Streamlit & AI")
121
 
122
  if __name__ == "__main__":
123
+ render_ui()