dawit45 commited on
Commit
b604e72
·
verified ·
1 Parent(s): 12b7c97

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +150 -101
app.py CHANGED
@@ -1,138 +1,187 @@
1
  import streamlit as st
2
- import json
3
  import pandas as pd
4
  import numpy as np
5
  import io
6
- from omni_agent_v8 import OMNIOrchestratorV8
7
- from omni_genomics import OMNIGenomics
8
-
9
- # PDF and QR Libraries
10
  from reportlab.lib.pagesizes import A4
11
  from reportlab.pdfgen import canvas
12
  from reportlab.lib.units import inch
13
- import qrcode
 
 
14
 
15
- # Page Configuration
16
- st.set_page_config(page_title="Abyssinia Intelligence V8", layout="wide")
17
 
18
- # Custom Gemini-style Response Styling
19
  st.markdown("""
20
  <style>
21
- .gemini-response {
22
- background-color: #ffffff;
23
- border: 1px solid #e3e3e3;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  padding: 25px;
25
- border-radius: 12px;
26
- color: #1f1f1f;
27
- font-family: sans-serif;
28
  line-height: 1.6;
29
  }
30
- .stButton>button { border-radius: 20px; background-color: #1a73e8; color: white; }
 
 
 
 
 
 
 
 
 
 
31
  </style>
32
  """, unsafe_allow_html=True)
33
 
34
- def generate_medical_pdf(report_text, genomic_risks, qr_data):
35
- """Generates a clinical PDF with QR code and electronic signature."""
36
  buffer = io.BytesIO()
37
- p = canvas.Canvas(buffer, pagesize=A4)
38
  width, height = A4
39
 
40
- # Header
41
- p.setFont("Helvetica-Bold", 16)
42
- p.drawString(1*inch, height - 1*inch, "ABYSSINIA INTELLIGENCE | PRECISION REPORT")
43
- p.setFont("Helvetica", 10)
44
- p.drawString(1*inch, height - 1.2*inch, "Date: 2026-02-12 | System Version: 8.0.2")
45
- p.line(1*inch, height - 1.3*inch, 7.2*inch, height - 1.3*inch)
46
-
47
- # Content
48
- text_object = p.beginText(1*inch, height - 1.7*inch)
49
- text_object.setFont("Helvetica", 11)
50
- text_object.setLeading(14)
51
 
52
- # Split text to fit page
53
- lines = report_text.split('\n')
54
- for line in lines[:30]: # Limit lines for one page demo
55
- text_object.textLine(line)
56
- p.drawText(text_object)
57
 
58
- # QR Code Generation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  qr = qrcode.make(qr_data)
60
- qr_path = "temp_qr.png"
61
- qr.save(qr_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
- # Footer: Signature and QR
64
- p.line(1*inch, 2.5*inch, 7.2*inch, 2.5*inch)
65
- p.drawImage(qr_path, 1*inch, 1*inch, width=1*inch, height=1*inch)
 
66
 
67
- p.setFont("Helvetica-Bold", 12)
68
- p.drawString(4*inch, 1.8*inch, "ELECTRONIC SIGNATURE")
69
- p.setFont("Helvetica-Oblique", 10)
70
- p.drawString(4*inch, 1.6*inch, "Digitally Verified by OMNI Orchestrator V8")
71
- p.drawString(4*inch, 1.4*inch, "ID: AB-2026-X9912")
72
-
73
- p.showPage()
74
- p.save()
75
  buffer.seek(0)
76
  return buffer
77
 
78
- # Initialize Agents
79
  orchestrator = OMNIOrchestratorV8(st.secrets["GEMINI_API_KEY"])
80
  genomics_engine = OMNIGenomics()
81
 
82
- # Sidebar
83
- with st.sidebar:
84
- st.title("Clinical Workspace")
85
- audio_file = st.audio_input("Record Encounter")
86
- vcf_upload = st.file_uploader("Genomic Data", type=['vcf', 'txt'])
87
 
88
- # Main UI
89
- st.title("Digital Twin Orchestrator")
90
- col_left, col_right = st.columns([1.2, 0.8])
91
 
92
- if st.button("Generate Digital Twin & Sign"):
93
- if audio_file and vcf_upload:
94
- with st.spinner("Analyzing and Signing Report..."):
95
- # 1. AI Logic
 
 
96
  soap_note = orchestrator.scribe_audio(audio_file.getvalue())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  genomic_risks = orchestrator.map_genomics(vcf_upload.getvalue().decode())
98
- final_report = orchestrator.synthesize_digital_twin(soap_note, genomic_risks)
99
 
100
- # 2. Store State
101
- st.session_state.final_report = final_report
102
- st.session_state.genomic_risks = genomic_risks
103
 
104
- # 3. Create JSON-LD
105
- digital_twin = {"@type": "MedicalReport", "content": final_report}
106
- st.session_state.json_ld = json.dumps(digital_twin)
107
-
108
- # 4. Generate PDF
109
- qr_link = "https://abyssinia.ai/verify/AB-2026-X9912"
110
- st.session_state.pdf_buffer = generate_medical_pdf(final_report, genomic_risks, qr_link)
111
-
112
- if 'final_report' in st.session_state:
113
- with col_left:
114
- st.subheader("Clinical Synthesis")
115
- st.markdown(f'<div class="gemini-response">{st.session_state.final_report}</div>', unsafe_allow_html=True)
116
-
117
- st.divider()
118
-
119
- # New Feature: Signed PDF Export
120
- st.download_button(
121
- label="Download Signed PDF Report",
122
- data=st.session_state.pdf_buffer,
123
- file_name="Signed_Medical_Report_V8.pdf",
124
- mime="application/pdf"
125
- )
126
-
127
- st.download_button(
128
- label="Export JSON-LD",
129
- data=st.session_state.json_ld,
130
- file_name="digital_twin.json",
131
- mime="application/ld+json"
132
- )
133
-
134
- with col_right:
135
- st.subheader("Genomic Risk Landscape")
136
- mock_df = pd.DataFrame({"Chromosome": np.random.randint(1, 23, 15), "Risk": np.random.rand(15)})
137
- st.plotly_chart(genomics_engine.plot_variant_density(mock_df), use_container_width=True)
138
- st.info(st.session_state.genomic_risks)
 
1
  import streamlit as st
 
2
  import pandas as pd
3
  import numpy as np
4
  import io
5
+ import qrcode
 
 
 
6
  from reportlab.lib.pagesizes import A4
7
  from reportlab.pdfgen import canvas
8
  from reportlab.lib.units import inch
9
+ from reportlab.lib.utils import ImageReader
10
+ from omni_agent_v8 import OMNIOrchestratorV8
11
+ from omni_genomics import OMNIGenomics
12
 
13
+ st.set_page_config(page_title="Abyssinia V8 | Precision", layout="wide")
 
14
 
15
+ # CSS: V8 "Stealth" UI + Gemini-Style Output Cards
16
  st.markdown("""
17
  <style>
18
+ /* Global Stealth Theme */
19
+ .stApp { background-color: #050505; color: #e3e3e3; }
20
+
21
+ /* Rounded Buttons */
22
+ .stButton button {
23
+ border-radius: 30px;
24
+ background: #1a1a1c;
25
+ border: 1px solid #333;
26
+ color: #e3e3e3;
27
+ transition: all 0.3s;
28
+ }
29
+ .stButton button:hover { border-color: #4285f4; color: #4285f4; }
30
+ .stButton button:active { background: #4285f4 !important; color: white; }
31
+
32
+ /* GEMINI-LIKE CARD (Dark Mode Optimized) */
33
+ .gemini-card {
34
+ background-color: #161618;
35
+ border: 1px solid #2d2d2d;
36
+ border-radius: 16px;
37
  padding: 25px;
38
+ margin-top: 10px;
39
+ box-shadow: 0 4px 20px rgba(0,0,0,0.5);
40
+ font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
41
  line-height: 1.6;
42
  }
43
+ .gemini-card h1, .gemini-card h2, .gemini-card h3 {
44
+ color: #8ab4f8; /* Gemini Blue for headers */
45
+ margin-top: 0;
46
+ font-weight: 500;
47
+ }
48
+ .gemini-card strong {
49
+ color: #ffffff;
50
+ }
51
+ .gemini-card ul {
52
+ margin-left: 20px;
53
+ }
54
  </style>
55
  """, unsafe_allow_html=True)
56
 
57
+ # --- PDF GENERATION ENGINE ---
58
+ def generate_signed_pdf(patient_text, genomics_text, qr_data):
59
  buffer = io.BytesIO()
60
+ c = canvas.Canvas(buffer, pagesize=A4)
61
  width, height = A4
62
 
63
+ # 1. Header & Logo Placeholder
64
+ c.setFillColorRGB(0.1, 0.1, 0.1) # Dark Text
65
+ c.setFont("Helvetica-Bold", 16)
66
+ c.drawString(1*inch, height - 1*inch, "ABYSSINIA INTELLIGENCE | PRECISION REPORT")
 
 
 
 
 
 
 
67
 
68
+ c.setFillColorRGB(0.4, 0.4, 0.4)
69
+ c.setFont("Helvetica", 10)
70
+ c.drawString(1*inch, height - 1.25*inch, f"Date: 2026-02-12 | Authorized By: OMNI V8 Orchestrator")
71
+ c.line(1*inch, height - 1.4*inch, 7.27*inch, height - 1.4*inch)
 
72
 
73
+ # 2. Body Text (Simple wrap for demo)
74
+ text_obj = c.beginText(1*inch, height - 1.8*inch)
75
+ text_obj.setFont("Helvetica", 11)
76
+ text_obj.setFillColorRGB(0, 0, 0)
77
+ text_obj.setLeading(14)
78
+
79
+ # Merging content for the PDF
80
+ full_content = f"CLINICAL SUMMARY:\n{patient_text}\n\nGENOMIC RISK FACTORS:\n{genomics_text}"
81
+
82
+ # Basic text wrapping (ReportLab usually requires Platypus for advanced wrapping,
83
+ # but this keeps it single-file simple)
84
+ lines = full_content.split('\n')
85
+ line_limit = 45
86
+ for line in lines[:line_limit]:
87
+ text_obj.textLine(line[:90]) # Truncate long lines to fit width
88
+ if len(lines) > line_limit:
89
+ text_obj.textLine("... [Content Truncated for One-Page Summary] ...")
90
+
91
+ c.drawText(text_obj)
92
+
93
+ # 3. QR Code & Electronic Signature
94
+ # Generate QR Image
95
  qr = qrcode.make(qr_data)
96
+ qr_buffer = io.BytesIO()
97
+ qr.save(qr_buffer, format="PNG")
98
+ qr_buffer.seek(0)
99
+ qr_img = ImageReader(qr_buffer)
100
+
101
+ # Draw Footer Line
102
+ c.setStrokeColorRGB(0.8, 0.8, 0.8)
103
+ c.line(1*inch, 2*inch, 7.27*inch, 2*inch)
104
+
105
+ # Draw QR
106
+ c.drawImage(qr_img, 1*inch, 0.7*inch, width=1.2*inch, height=1.2*inch)
107
+
108
+ # Draw Signature Text
109
+ c.setFont("Helvetica-Bold", 12)
110
+ c.setFillColorRGB(0, 0, 0)
111
+ c.drawString(2.5*inch, 1.5*inch, "ELECTRONICALLY SIGNED")
112
 
113
+ c.setFont("Courier", 9)
114
+ c.setFillColorRGB(0.3, 0.3, 0.3)
115
+ c.drawString(2.5*inch, 1.3*inch, f"Hash: {hash(full_content)}")
116
+ c.drawString(2.5*inch, 1.15*inch, "Verification: https://abyssinia.ai/verify")
117
 
118
+ c.save()
 
 
 
 
 
 
 
119
  buffer.seek(0)
120
  return buffer
121
 
122
+ # --- INITIALIZATION ---
123
  orchestrator = OMNIOrchestratorV8(st.secrets["GEMINI_API_KEY"])
124
  genomics_engine = OMNIGenomics()
125
 
126
+ st.title("Abyssinia Intelligence V8")
127
+ st.caption("Ambient Intelligence & Pharmacogenomics | System Status: ONLINE")
 
 
 
128
 
129
+ col_ambient, col_genomics = st.columns([1, 1])
 
 
130
 
131
+ with col_ambient:
132
+ st.subheader("Ambient Scribe")
133
+ audio_file = st.audio_input("Record Patient Encounter")
134
+
135
+ if audio_file:
136
+ with st.spinner("Scribing..."):
137
  soap_note = orchestrator.scribe_audio(audio_file.getvalue())
138
+ st.session_state.soap_note = soap_note
139
+ # UPDATED: Cleaner display than code block
140
+ st.info(f"Transcript Processed: {len(soap_note)} chars")
141
+
142
+ with col_genomics:
143
+ st.subheader("Genomic Mapping")
144
+ vcf_upload = st.file_uploader("Upload Genomic (VCF) Data", type=['vcf', 'txt'])
145
+
146
+ if vcf_upload:
147
+ # Simulated VCF analysis
148
+ vcf_data = pd.DataFrame({
149
+ "Chromosome": np.random.randint(1, 23, 50),
150
+ "Position": np.random.randint(1000, 1000000, 50),
151
+ "Risk_Score": np.random.rand(50),
152
+ "Clinical_Significance": np.random.randint(1, 10, 50)
153
+ })
154
+ st.plotly_chart(genomics_engine.plot_variant_density(vcf_data))
155
+
156
+ if st.button("Generate Precision Synthesis"):
157
+ if 'soap_note' in st.session_state and vcf_upload:
158
+ with st.spinner("Orchestrating Multi-Agent Swarm..."):
159
  genomic_risks = orchestrator.map_genomics(vcf_upload.getvalue().decode())
 
160
 
161
+ # Using the Corrected V8 Method Name
162
+ final_report = orchestrator.synthesize_digital_twin(st.session_state.soap_note, genomic_risks)
 
163
 
164
+ # 1. DISPLAY: Gemini-Style Card (Markdown with CSS class)
165
+ st.markdown(f"""
166
+ <div class="gemini-card">
167
+ {final_report}
168
+ </div>
169
+ """, unsafe_allow_html=True)
170
+
171
+ # 2. GENERATE PDF: With Signature & QR
172
+ pdf_data = generate_signed_pdf(
173
+ st.session_state.soap_note,
174
+ genomic_risks,
175
+ "Abyssinia-V8-Patient-ID-5501"
176
+ )
177
+
178
+ # 3. EXPORT BUTTON
179
+ st.download_button(
180
+ label="Download Signed Clinical Report (PDF)",
181
+ data=pdf_data,
182
+ file_name="Abyssinia_Signed_Report.pdf",
183
+ mime="application/pdf"
184
+ )
185
+
186
+ else:
187
+ st.error("Incomplete Data: V8 requires both Ambient Scribe and Genomic Data.")