mgbam commited on
Commit
4a6179c
Β·
verified Β·
1 Parent(s): 9c2f1fc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -44
app.py CHANGED
@@ -1,6 +1,6 @@
1
- # app.py
2
- import asyncio, re
3
- from pathlib import Path
4
 
5
  import streamlit as st
6
  import pandas as pd
@@ -8,53 +8,63 @@ import plotly.express as px
8
  from fpdf import FPDF
9
  from streamlit_agraph import agraph
10
 
11
- from mcp.orchestrator import orchestrate_search, answer_ai_question
12
  from mcp.knowledge_graph import build_agraph
13
- from mcp.graph_metrics import build_nx, get_top_hubs, get_density
 
14
 
 
15
  st.set_page_config(layout="wide", page_title="MedGenesis AI")
16
  if "res" not in st.session_state:
17
  st.session_state.res = None
18
 
19
  st.title("🧬 MedGenesis AI")
20
- llm = st.radio("LLM engine", ["openai","gemini"], horizontal=True)
21
- query= st.text_input("Enter biomedical question")
 
 
22
 
23
  def _make_pdf(papers):
24
- pdf = FPDF(); pdf.add_page(); pdf.set_font("Helvetica",size=12)
25
- pdf.cell(0,10,"MedGenesis AI – Results",ln=True,align="C"); pdf.ln(5)
26
- for i,p in enumerate(papers,1):
27
- pdf.set_font("Helvetica","B",11); pdf.multi_cell(0,7,f"{i}. {p.get('title','')}")
28
- pdf.set_font("Helvetica",size=9)
29
- body = f"{p.get('authors','')}\n{p.get('summary','')}\n{p.get('link','')}"
30
- pdf.multi_cell(0,6,body); pdf.ln(3)
31
- return pdf.output(dest="S").encode("latin-1",errors="replace")
 
 
 
 
32
 
 
33
  if st.button("Run Search πŸš€") and query:
34
  with st.spinner("Gathering data…"):
35
  st.session_state.res = asyncio.run(orchestrate_search(query, llm))
36
  res = st.session_state.res
37
-
38
  if not res:
39
  st.info("Enter a query and press Run Search")
40
  st.stop()
41
 
 
 
 
42
  # ── Results tab
43
- tabs = st.tabs(["Results","Graph","Variants","Trials","Metrics","Visuals"])
44
  with tabs[0]:
45
- for i,p in enumerate(res["papers"],1):
46
  st.markdown(f"**{i}. [{p['title']}]({p['link']})**")
47
  st.write(p["summary"])
48
- c1,c2 = st.columns(2)
49
  c1.download_button("CSV", pd.DataFrame(res["papers"]).to_csv(index=False),
50
- "papers.csv","text/csv")
51
  c2.download_button("PDF", _make_pdf(res["papers"]),
52
- "papers.pdf","application/pdf")
53
  st.subheader("AI summary"); st.info(res["ai_summary"])
54
 
55
  # ── Graph tab
56
  with tabs[1]:
57
- nodes,edges,cfg = build_agraph(
58
  res["papers"], res["umls"], res["drug_safety"], res["umls_relations"]
59
  )
60
  hl = st.text_input("Highlight node:", key="hl")
@@ -64,40 +74,88 @@ with tabs[1]:
64
  n.color = "#f1c40f" if pat.search(n.label) else n.color
65
  agraph(nodes, edges, cfg)
66
 
67
- # ── Variants tab
68
  with tabs[2]:
69
- if res["variants"]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  st.json(res["variants"])
71
  else:
72
- st.warning("No variants found. Try β€˜TP53’ or β€˜BRCA1’.")
73
 
74
  # ── Trials tab
75
- with tabs[3]:
76
- if res["clinical_trials"]:
77
  st.json(res["clinical_trials"])
78
  else:
79
  st.warning("No trials found. Try a disease or drug.")
80
 
81
  # ── Metrics tab
82
- with tabs[4]:
83
- G = build_nx([n.__dict__ for n in nodes],[e.__dict__ for e in edges])
 
 
84
  st.metric("Density", f"{get_density(G):.3f}")
85
  st.markdown("**Top hubs**")
86
- for nid,sc in get_top_hubs(G):
87
- lbl = next((n.label for n in nodes if n.id==nid), nid)
88
  st.write(f"- {lbl}: {sc:.3f}")
89
 
90
  # ── Visuals tab
91
- with tabs[5]:
92
- yrs = [p.get("published","")[:4] for p in res["papers"] if p.get("published")]
93
- if yrs:
94
- st.plotly_chart(px.histogram(yrs,nbins=10,title="Publication Year"))
95
-
96
- # ── Follow-up QA
97
- st.markdown("---")
98
- q = st.text_input("Ask follow-up question:", key="followup_input")
99
- if st.button("Ask AI"):
100
- with st.spinner("Querying LLM…"):
101
- ans = asyncio.run(answer_ai_question(
102
- q, context=res["ai_summary"], llm=llm))
103
- st.write(ans["answer"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ── app.py ─────────────────────────────────────────────────────────────
2
+ import asyncio
3
+ import re
4
 
5
  import streamlit as st
6
  import pandas as pd
 
8
  from fpdf import FPDF
9
  from streamlit_agraph import agraph
10
 
11
+ from mcp.orchestrator import orchestrate_search, answer_ai_question
12
  from mcp.knowledge_graph import build_agraph
13
+ from mcp.graph_metrics import build_nx, get_top_hubs, get_density
14
+ from mcp.protocols import draft_protocol
15
 
16
+ # ── Streamlit setup ────────────────────────────────────────────────────
17
  st.set_page_config(layout="wide", page_title="MedGenesis AI")
18
  if "res" not in st.session_state:
19
  st.session_state.res = None
20
 
21
  st.title("🧬 MedGenesis AI")
22
+ llm = st.radio("LLM engine", ["openai", "gemini"], horizontal=True)
23
+ query = st.text_input("Enter biomedical question")
24
+
25
+ # PDF helper
26
 
27
  def _make_pdf(papers):
28
+ pdf = FPDF()
29
+ pdf.add_page(); pdf.set_font("Helvetica", size=12)
30
+ pdf.cell(0, 10, "MedGenesis AI – Results", ln=True, align="C"); pdf.ln(5)
31
+ for i, p in enumerate(papers, 1):
32
+ pdf.set_font("Helvetica", "B", 11)
33
+ pdf.multi_cell(0, 7, f"{i}. {p.get('title','')}")
34
+ pdf.set_font("Helvetica", size=9)
35
+ body = f"{p.get('authors','')}
36
+ {p.get('summary','')}
37
+ {p.get('link','')}"
38
+ pdf.multi_cell(0, 6, body); pdf.ln(3)
39
+ return pdf.output(dest="S").encode("latin-1", errors="replace")
40
 
41
+ # Run search
42
  if st.button("Run Search πŸš€") and query:
43
  with st.spinner("Gathering data…"):
44
  st.session_state.res = asyncio.run(orchestrate_search(query, llm))
45
  res = st.session_state.res
 
46
  if not res:
47
  st.info("Enter a query and press Run Search")
48
  st.stop()
49
 
50
+ # Tabs
51
+ tabs = st.tabs(["Results", "Graph", "Clusters", "Variants", "Trials", "Metrics", "Visuals", "Protocols"])
52
+
53
  # ── Results tab
 
54
  with tabs[0]:
55
+ for i, p in enumerate(res["papers"], 1):
56
  st.markdown(f"**{i}. [{p['title']}]({p['link']})**")
57
  st.write(p["summary"])
58
+ c1, c2 = st.columns(2)
59
  c1.download_button("CSV", pd.DataFrame(res["papers"]).to_csv(index=False),
60
+ "papers.csv", "text/csv")
61
  c2.download_button("PDF", _make_pdf(res["papers"]),
62
+ "papers.pdf", "application/pdf")
63
  st.subheader("AI summary"); st.info(res["ai_summary"])
64
 
65
  # ── Graph tab
66
  with tabs[1]:
67
+ nodes, edges, cfg = build_agraph(
68
  res["papers"], res["umls"], res["drug_safety"], res["umls_relations"]
69
  )
70
  hl = st.text_input("Highlight node:", key="hl")
 
74
  n.color = "#f1c40f" if pat.search(n.label) else n.color
75
  agraph(nodes, edges, cfg)
76
 
77
+ # ── Clusters tab
78
  with tabs[2]:
79
+ clusters = res.get("clusters", [])
80
+ if clusters:
81
+ df = pd.DataFrame({
82
+ "title": [p['title'] for p in res['papers']],
83
+ "cluster": clusters
84
+ })
85
+ st.write("### Paper Clusters")
86
+ for c in sorted(set(clusters)):
87
+ st.write(f"**Cluster {c}**")
88
+ for t in df[df['cluster'] == c]['title']:
89
+ st.write(f"- {t}")
90
+ else:
91
+ st.info("No clusters to show.")
92
+
93
+ # ── Variants tab
94
+ with tabs[3]:
95
+ if res.get("variants"):
96
  st.json(res["variants"])
97
  else:
98
+ st.warning("No variants found. Try 'TP53' or 'BRCA1'.")
99
 
100
  # ── Trials tab
101
+ with tabs[4]:
102
+ if res.get("clinical_trials"):
103
  st.json(res["clinical_trials"])
104
  else:
105
  st.warning("No trials found. Try a disease or drug.")
106
 
107
  # ── Metrics tab
108
+ with tabs[5]:
109
+ nodes_dicts = [n.__dict__ for n in nodes]
110
+ edges_dicts = [e.__dict__ for e in edges]
111
+ G = build_nx(nodes_dicts, edges_dicts)
112
  st.metric("Density", f"{get_density(G):.3f}")
113
  st.markdown("**Top hubs**")
114
+ for nid, sc in get_top_hubs(G):
115
+ lbl = next((n.label for n in nodes if n.id == nid), nid)
116
  st.write(f"- {lbl}: {sc:.3f}")
117
 
118
  # ── Visuals tab
119
+ with tabs[6]:
120
+ years = [p.get("published","")[:4] for p in res["papers"] if p.get("published")]
121
+ if years:
122
+ st.plotly_chart(px.histogram(years, nbins=10, title="Publication Year"))
123
+
124
+ # ── Protocols tab
125
+ with tabs[7]:
126
+ proto_q = st.text_input("Enter hypothesis for protocol:", key="proto_q")
127
+ if st.button("Draft Protocol") and proto_q.strip():
128
+ with st.spinner("Generating protocol…"):
129
+ proto = asyncio.run(draft_protocol(
130
+ proto_q, context=res['ai_summary'], llm=llm
131
+ ))
132
+ st.subheader("Experimental Protocol")
133
+ st.write(proto)
134
+ ───────────────────────────────────────────────────
135
+ # In import section:
136
+ from mcp.embeddings import embed_texts, cluster_embeddings
137
+ from mcp.protocols import draft_protocol
138
+
139
+ # After creating tabs = st.tabs([...,'Clusters','Protocols']):
140
+ with tabs[-2]: # second last tab = Clusters
141
+ if res.get('clusters'):
142
+ df = pd.DataFrame({
143
+ 'title': [p['title'] for p in res['papers']],
144
+ 'cluster': res['clusters']
145
+ })
146
+ st.write("### Paper Clusters")
147
+ for c in sorted(set(res['clusters'])):
148
+ st.write(f"**Cluster {c}**")
149
+ for t in df[df['cluster']==c]['title']:
150
+ st.write(f"- {t}")
151
+ else:
152
+ st.info("No clusters to show.")
153
+
154
+ with tabs[-1]: # last tab = Protocols
155
+ proto_q = st.text_input("Enter hypothesis for protocol:", key="proto_q")
156
+ if st.button("Draft Protocol") and proto_q.strip():
157
+ with st.spinner("Generating protocol…"):
158
+ proto = asyncio.run(draft_protocol(
159
+ proto_q, context=res['ai_summary'], llm=llm))
160
+ st.subheader("Experimental Protocol")
161
+ st.write(proto)