dawit45's picture
Update app.py
b604e72 verified
import streamlit as st
import pandas as pd
import numpy as np
import io
import qrcode
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
from reportlab.lib.utils import ImageReader
from omni_agent_v8 import OMNIOrchestratorV8
from omni_genomics import OMNIGenomics
st.set_page_config(page_title="Abyssinia V8 | Precision", layout="wide")
# CSS: V8 "Stealth" UI + Gemini-Style Output Cards
st.markdown("""
<style>
/* Global Stealth Theme */
.stApp { background-color: #050505; color: #e3e3e3; }
/* Rounded Buttons */
.stButton button {
border-radius: 30px;
background: #1a1a1c;
border: 1px solid #333;
color: #e3e3e3;
transition: all 0.3s;
}
.stButton button:hover { border-color: #4285f4; color: #4285f4; }
.stButton button:active { background: #4285f4 !important; color: white; }
/* GEMINI-LIKE CARD (Dark Mode Optimized) */
.gemini-card {
background-color: #161618;
border: 1px solid #2d2d2d;
border-radius: 16px;
padding: 25px;
margin-top: 10px;
box-shadow: 0 4px 20px rgba(0,0,0,0.5);
font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
line-height: 1.6;
}
.gemini-card h1, .gemini-card h2, .gemini-card h3 {
color: #8ab4f8; /* Gemini Blue for headers */
margin-top: 0;
font-weight: 500;
}
.gemini-card strong {
color: #ffffff;
}
.gemini-card ul {
margin-left: 20px;
}
</style>
""", unsafe_allow_html=True)
# --- PDF GENERATION ENGINE ---
def generate_signed_pdf(patient_text, genomics_text, qr_data):
buffer = io.BytesIO()
c = canvas.Canvas(buffer, pagesize=A4)
width, height = A4
# 1. Header & Logo Placeholder
c.setFillColorRGB(0.1, 0.1, 0.1) # Dark Text
c.setFont("Helvetica-Bold", 16)
c.drawString(1*inch, height - 1*inch, "ABYSSINIA INTELLIGENCE | PRECISION REPORT")
c.setFillColorRGB(0.4, 0.4, 0.4)
c.setFont("Helvetica", 10)
c.drawString(1*inch, height - 1.25*inch, f"Date: 2026-02-12 | Authorized By: OMNI V8 Orchestrator")
c.line(1*inch, height - 1.4*inch, 7.27*inch, height - 1.4*inch)
# 2. Body Text (Simple wrap for demo)
text_obj = c.beginText(1*inch, height - 1.8*inch)
text_obj.setFont("Helvetica", 11)
text_obj.setFillColorRGB(0, 0, 0)
text_obj.setLeading(14)
# Merging content for the PDF
full_content = f"CLINICAL SUMMARY:\n{patient_text}\n\nGENOMIC RISK FACTORS:\n{genomics_text}"
# Basic text wrapping (ReportLab usually requires Platypus for advanced wrapping,
# but this keeps it single-file simple)
lines = full_content.split('\n')
line_limit = 45
for line in lines[:line_limit]:
text_obj.textLine(line[:90]) # Truncate long lines to fit width
if len(lines) > line_limit:
text_obj.textLine("... [Content Truncated for One-Page Summary] ...")
c.drawText(text_obj)
# 3. QR Code & Electronic Signature
# Generate QR Image
qr = qrcode.make(qr_data)
qr_buffer = io.BytesIO()
qr.save(qr_buffer, format="PNG")
qr_buffer.seek(0)
qr_img = ImageReader(qr_buffer)
# Draw Footer Line
c.setStrokeColorRGB(0.8, 0.8, 0.8)
c.line(1*inch, 2*inch, 7.27*inch, 2*inch)
# Draw QR
c.drawImage(qr_img, 1*inch, 0.7*inch, width=1.2*inch, height=1.2*inch)
# Draw Signature Text
c.setFont("Helvetica-Bold", 12)
c.setFillColorRGB(0, 0, 0)
c.drawString(2.5*inch, 1.5*inch, "ELECTRONICALLY SIGNED")
c.setFont("Courier", 9)
c.setFillColorRGB(0.3, 0.3, 0.3)
c.drawString(2.5*inch, 1.3*inch, f"Hash: {hash(full_content)}")
c.drawString(2.5*inch, 1.15*inch, "Verification: https://abyssinia.ai/verify")
c.save()
buffer.seek(0)
return buffer
# --- INITIALIZATION ---
orchestrator = OMNIOrchestratorV8(st.secrets["GEMINI_API_KEY"])
genomics_engine = OMNIGenomics()
st.title("Abyssinia Intelligence V8")
st.caption("Ambient Intelligence & Pharmacogenomics | System Status: ONLINE")
col_ambient, col_genomics = st.columns([1, 1])
with col_ambient:
st.subheader("Ambient Scribe")
audio_file = st.audio_input("Record Patient Encounter")
if audio_file:
with st.spinner("Scribing..."):
soap_note = orchestrator.scribe_audio(audio_file.getvalue())
st.session_state.soap_note = soap_note
# UPDATED: Cleaner display than code block
st.info(f"Transcript Processed: {len(soap_note)} chars")
with col_genomics:
st.subheader("Genomic Mapping")
vcf_upload = st.file_uploader("Upload Genomic (VCF) Data", type=['vcf', 'txt'])
if vcf_upload:
# Simulated VCF analysis
vcf_data = pd.DataFrame({
"Chromosome": np.random.randint(1, 23, 50),
"Position": np.random.randint(1000, 1000000, 50),
"Risk_Score": np.random.rand(50),
"Clinical_Significance": np.random.randint(1, 10, 50)
})
st.plotly_chart(genomics_engine.plot_variant_density(vcf_data))
if st.button("Generate Precision Synthesis"):
if 'soap_note' in st.session_state and vcf_upload:
with st.spinner("Orchestrating Multi-Agent Swarm..."):
genomic_risks = orchestrator.map_genomics(vcf_upload.getvalue().decode())
# Using the Corrected V8 Method Name
final_report = orchestrator.synthesize_digital_twin(st.session_state.soap_note, genomic_risks)
# 1. DISPLAY: Gemini-Style Card (Markdown with CSS class)
st.markdown(f"""
<div class="gemini-card">
{final_report}
</div>
""", unsafe_allow_html=True)
# 2. GENERATE PDF: With Signature & QR
pdf_data = generate_signed_pdf(
st.session_state.soap_note,
genomic_risks,
"Abyssinia-V8-Patient-ID-5501"
)
# 3. EXPORT BUTTON
st.download_button(
label="Download Signed Clinical Report (PDF)",
data=pdf_data,
file_name="Abyssinia_Signed_Report.pdf",
mime="application/pdf"
)
else:
st.error("Incomplete Data: V8 requires both Ambient Scribe and Genomic Data.")