import streamlit as st
from pdfhandle import parse_medical_pdf
from analyze import analyze_parameter, generate_report_summary
from voice import get_medical_report_answer, play_audio_response
import os
import tempfile
import base64
import pandas as pd
st.set_page_config(
page_title="AI Doctor",
layout="wide",
page_icon="🩺"
)
# Custom CSS for enhanced styling
st.markdown("""
""", unsafe_allow_html=True)
# Header with icons and tagline
st.markdown('
', unsafe_allow_html=True)
st.markdown('AI Doctor
', unsafe_allow_html=True)
st.markdown('Empowering people through AI-powered health insights in their native language
', unsafe_allow_html=True)
# Initialize session state for storing analysis results
if 'raw_data' not in st.session_state:
st.session_state.raw_data = None
if 'categorized' not in st.session_state:
st.session_state.categorized = None
if 'summary' not in st.session_state:
st.session_state.summary = None
if 'voice_response' not in st.session_state:
st.session_state.voice_response = None
# Add active tab tracking to session state
if 'active_tab' not in st.session_state:
st.session_state.active_tab = 0
# Styled file upload section
st.markdown('', unsafe_allow_html=True)
uploaded_file = st.file_uploader(
"Upload Medical Report (PDF, max 10MB)",
type="pdf",
help="We never store your medical data. All processing happens on-demand.",
accept_multiple_files=False
)
st.markdown('
', unsafe_allow_html=True)
def get_binary_file_downloader_html(bin_file, file_label='File'):
with open(bin_file, 'rb') as f:
data = f.read()
b64 = base64.b64encode(data).decode()
href = f'Download {file_label} 📥'
return href
# Function to update active tab in session state
def set_active_tab(tab_idx):
st.session_state.active_tab = tab_idx
# Main application flow
if uploaded_file:
if uploaded_file.size > 10 * 1024 * 1024:
st.error("❌ File size exceeds 10MB limit")
st.stop()
# Only process the PDF if it hasn't been processed yet or a new file was uploaded
file_hash = hash(uploaded_file.getvalue())
if 'file_hash' not in st.session_state or file_hash != st.session_state.file_hash:
with st.spinner("Analyzing your medical report..."):
try:
# Process PDF
st.session_state.raw_data = parse_medical_pdf(uploaded_file)
st.session_state.file_hash = file_hash
if not st.session_state.raw_data:
st.error("No parameters found in document. Please ensure this is a standard medical report.")
st.stop()
# Generate summary
st.session_state.summary = generate_report_summary(st.session_state.raw_data)
# Process analysis
categorized = {
"Good": [],
"Moderate": [],
"Immediate Attention": []
}
for item in st.session_state.raw_data:
analysis = analyze_parameter(
item["test"],
item["value"],
item["reference"]
)
row = {
"Parameter": item["test"],
"Value": f"{item['value']} (Ref: {item['reference']})",
"Clinical Significance": analysis["reason"],
"Dietary Recommendation": analysis["food"],
"Activity Guidance": analysis["exercise"],
"Status": analysis["status"]
}
categorized[analysis["status"]].append(row)
st.session_state.categorized = categorized
except Exception as e:
st.error(f"Analysis failed: {str(e)}")
st.stop()
# Create tabs with specified active tab from session state and improved icons
tab_titles = ["📊 Summary", "🔍 Detailed Analysis", "🗣️ Voice Assistant"]
# Create tab containers with the active tab selected
active_tab_index = st.session_state.active_tab
tabs = st.tabs(tab_titles)
# Tab 1: Summary with enhanced cards
with tabs[0]:
st.markdown("", unsafe_allow_html=True)
st.markdown(f"{st.session_state.summary}
", unsafe_allow_html=True)
# Summary stats with improved metric cards
st.markdown("Health Parameters Overview
", unsafe_allow_html=True)
col1, col2, col3 = st.columns(3)
with col1:
good_count = len(st.session_state.categorized["Good"])
st.markdown(f"""
Good Parameters
{good_count}
Normal range values
""", unsafe_allow_html=True)
with col2:
moderate_count = len(st.session_state.categorized["Moderate"])
st.markdown(f"""
Moderate Parameters
{moderate_count}
Borderline values
""", unsafe_allow_html=True)
with col3:
attention_count = len(st.session_state.categorized["Immediate Attention"])
st.markdown(f"""
Needs Attention
{attention_count}
Critical values
""", unsafe_allow_html=True)
# Tab 2: Detailed Analysis with improved styling
with tabs[1]:
st.markdown("", unsafe_allow_html=True)
st.warning("❗ This tool provides general insights only. Always consult a healthcare professional.")
# Create tables for each status category with improved styling
for status in ["Immediate Attention", "Moderate", "Good"]:
if data := st.session_state.categorized[status]:
status_color = "attention" if status == "Immediate Attention" else "moderate" if status == "Moderate" else "good"
status_icon = "⚠️" if status == "Immediate Attention" else "⚠️" if status == "Moderate" else "✅"
with st.expander(f"{status_icon} {status} Parameters ({len(data)})", expanded=(status == "Immediate Attention")):
# Convert list of dictionaries to DataFrame for tabular display
df = pd.DataFrame(data)
# Apply styling based on status
st.markdown(f"", unsafe_allow_html=True)
st.dataframe(
df,
hide_index=True,
use_container_width=True
)
st.markdown("
", unsafe_allow_html=True)
# Tab 3: Voice Assistant with improved layout
with tabs[2]:
st.markdown("", unsafe_allow_html=True)
st.info("You can ask questions about your medical report in Tamil. The assistant will respond in Tamil.")
# Create a placeholder for status messages
status_placeholder = st.empty()
# Remove doctor icon and adjust spacing
col1, col2 = st.columns(2)
with col1:
# Button for voice input
if st.button("🎤 Ask Questions (you may speak in Tamil)", type="primary", key="listen_button"):
# Update the active tab in session state
st.session_state.active_tab = 2
# Process voice input
st.session_state.voice_response = get_medical_report_answer(st.session_state.summary)
# Use JavaScript to ensure we stay on Voice Assistant tab
st.components.v1.html("""
""", height=0)
with col2:
# Text input as an alternative with better styling
tamil_text = st.text_input("💬 Or type your question in Tamil:", placeholder="என் இரத்த அழுத்தம் எப்படி உள்ளது?")
if tamil_text and st.button("✓ Submit", key="submit_button"):
# Update the active tab in session state
st.session_state.active_tab = 2
with st.spinner("Processing your query..."):
st.session_state.voice_response = get_medical_report_answer(st.session_state.summary, tamil_text)
# Use JavaScript to ensure we stay on Voice Assistant tab
st.components.v1.html("""
""", height=0)
# Display voice response in a more visually appealing way
if 'voice_response' in st.session_state and st.session_state.voice_response:
response = st.session_state.voice_response
# Clear any status messages
status_placeholder.empty()
# Original query display with improved styling
if response["original_query"]:
st.markdown("Your Question
", unsafe_allow_html=True)
st.markdown(f"""
Tamil: {response['original_query']}
English: {response['translated_query']}
""", unsafe_allow_html=True)
# Response display with improved styling
st.markdown("Response
", unsafe_allow_html=True)
with st.expander("🇺🇸 English Response", expanded=False):
st.markdown(f"{response['english_response']}
", unsafe_allow_html=True)
with st.expander("🇮🇳 Tamil Response", expanded=True):
st.markdown(f"{response['tamil_response']}
", unsafe_allow_html=True)
# Audio playback with auto-play and improved styling
if response["audio_file"] and os.path.exists(response["audio_file"]):
st.markdown("🔊 Voice Response
", unsafe_allow_html=True)
# Auto-play the audio
play_audio_response(response["audio_file"])
# Display audio controls for manual replay
st.audio(response["audio_file"])
# Download button with better styling
st.markdown(get_binary_file_downloader_html(response["audio_file"], 'Audio Response'), unsafe_allow_html=True)
# We don't need complex JavaScript for tabs anymore since we're using direct click events
# This is much simpler and more reliable
else:
# Show info when no file is uploaded with more attractive layout
st.info("Upload your medical report PDF to get started with your personalized health analysis")
# Sample information about the app with better formatting
col1, col2 = st.columns(2)
with col1:
st.markdown("""
How it works
- Upload your medical report in PDF format
- Our AI analyzes each parameter and provides:
- Status classification
- Clinical significance
- Dietary recommendations
- Activity guidance
- Ask questions in Tamil about your report using voice or text
""", unsafe_allow_html=True)
with col2:
st.markdown("""
Privacy & Security
- Your medical data is processed securely and never stored
- All analysis happens on-demand
- Voice data is only used for processing your queries
- We prioritize your data privacy and security
""", unsafe_allow_html=True)
# Footer with improved styling
st.markdown("""
""", unsafe_allow_html=True)
# Display LinkedIn profile
st.markdown(
"""
""",
unsafe_allow_html=True
)