Spaces:
Sleeping
Sleeping
File size: 6,643 Bytes
ed5d5d7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | """
Human+ β Page 2: AI Analysis
Refactored: loading states & biomarker rows pakai Streamlit native.
"""
import streamlit as st
from ui.components import (
render_loading_steps,
render_progress_bar,
render_section_label,
render_error_state,
render_biomarker_summary_banner,
render_biomarker_row,
render_success_banner,
ANALYSIS_STEPS,
)
from ui.chart_components import (
render_gauge_grid,
render_biomarker_bar_chart,
render_status_donut,
)
def render_analysis_page():
if not st.session_state.get("uploaded_pdf_bytes"):
render_error_state(
title="Tidak ada file PDF",
message="Silakan kembali ke langkah pertama dan upload hasil lab Anda.",
)
if st.button("β Kembali ke Upload", use_container_width=True):
st.session_state.step = 1
st.rerun()
return
if st.session_state.get("extracted_biomarkers") is not None:
_render_biomarker_results()
return
_run_analysis()
# ββ Analysis runner ββββββββββββββββββββββββββββββββββββββββββββββββββ
def _run_analysis():
render_section_label("MENGANALISIS LAB ANDA", "β‘")
status_ph = st.empty()
progress_ph = st.empty()
steps_ph = st.empty()
def _update(step_idx: int, msg: str):
with status_ph:
st.caption(f"βοΈ {msg}...")
with progress_ph:
render_progress_bar((step_idx + 0.5) / len(ANALYSIS_STEPS))
with steps_ph:
render_loading_steps(ANALYSIS_STEPS, step_idx)
# Step 0 β warm up vector store
_update(0, ANALYSIS_STEPS[0])
try:
from core.rag_engine import get_vector_store
get_vector_store()
except Exception:
pass
# Step 1 β Gemini PDF extraction
_update(1, ANALYSIS_STEPS[1])
try:
from core.pdf_processor import extract_biomarkers
biomarkers = extract_biomarkers(st.session_state.uploaded_pdf_bytes)
except Exception as e:
_clear(steps_ph, status_ph, progress_ph)
render_error_state(
title="Gagal Menganalisis PDF",
message=f"{e}\n\nPastikan PDF berisi hasil lab yang valid dan terbaca.",
show_contact=True,
)
col1, col2 = st.columns(2)
with col1:
if st.button("β Upload Lagi", use_container_width=True):
st.session_state.step = 1
st.session_state.uploaded_pdf_bytes = None
st.rerun()
with col2:
if st.button("π Coba Lagi", type="primary", use_container_width=True):
st.rerun()
return
# Step 2 & 3 β finalize
_update(2, ANALYSIS_STEPS[2])
import time; time.sleep(0.3)
_update(3, ANALYSIS_STEPS[3])
import time; time.sleep(0.3)
st.session_state.extracted_biomarkers = biomarkers
with progress_ph:
render_progress_bar(1.0)
with status_ph:
st.caption("β
Analisis selesai")
import time; time.sleep(0.4)
st.rerun()
def _clear(*placeholders):
for ph in placeholders:
ph.empty()
# ββ Results renderer βββββββββββββββββββββββββββββββββββββββββββββββββ
def _render_biomarker_results():
biomarkers = st.session_state.extracted_biomarkers
if not biomarkers:
render_error_state(
title="Tidak ada biomarker terdeteksi",
message="Coba upload file PDF yang lebih jelas atau format hasil lab standar.",
show_contact=True,
)
if st.button("β Upload Ulang", use_container_width=True):
for k in ["uploaded_pdf_bytes", "extracted_biomarkers", "generated_protocol"]:
st.session_state[k] = None
st.session_state.step = 1
st.rerun()
return
optimal = sum(1 for b in biomarkers if b["status"] == "optimal")
warning = sum(1 for b in biomarkers if b["status"] == "warning")
danger = sum(1 for b in biomarkers if b["status"] == "danger")
render_success_banner(
title=f"{len(biomarkers)} biomarker berhasil dianalisis",
subtitle="Dibandingkan dengan Human+ optimal ranges β bukan range lab standar",
)
render_biomarker_summary_banner(optimal, warning, danger)
# ββ Charts ββββββββββββββββββββββββββββββββββββββββββββββββββββ
render_section_label("VISUALISASI BIOMARKER", "π")
col_donut, col_bar = st.columns([1, 2])
with col_donut:
render_status_donut(optimal, warning, danger)
with col_bar:
render_biomarker_bar_chart(biomarkers)
render_section_label("GAUGE β MARKER PRIORITAS", "π―")
render_gauge_grid(biomarkers)
# ββ Biomarker rows βββββββββββββββββββββββββββββββββββββββββββββ
if danger:
render_section_label(f"PERLU PERHATIAN β {danger} MARKER", "π΄")
for b in biomarkers:
if b["status"] == "danger":
render_biomarker_row(b["name"], b["value"], b["unit"], b["status"], b.get("reference", ""))
if warning:
render_section_label(f"SUB-OPTIMAL β {warning} MARKER", "π‘")
for b in biomarkers:
if b["status"] == "warning":
render_biomarker_row(b["name"], b["value"], b["unit"], b["status"], b.get("reference", ""))
if optimal:
render_section_label(f"SUDAH OPTIMAL β {optimal} MARKER", "π’")
for b in biomarkers:
if b["status"] == "optimal":
render_biomarker_row(b["name"], b["value"], b["unit"], b["status"], b.get("reference", ""))
neutral = [b for b in biomarkers if b["status"] == "neutral"]
if neutral:
with st.expander(f"π {len(neutral)} marker lainnya"):
for b in neutral:
render_biomarker_row(b["name"], b["value"], b["unit"], "neutral", "")
st.write("")
if st.button("π¬ Generate Protocol Personal Saya", type="primary", use_container_width=True):
st.session_state.step = 3
st.rerun()
if st.button("β Upload Lab Lain", use_container_width=True):
for k in ["uploaded_pdf_bytes", "extracted_biomarkers", "generated_protocol", "pdf_filename"]:
st.session_state[k] = None
st.session_state.step = 1
st.rerun()
|