import os import streamlit as st import pandas as pd import plotly.express as px import plotly.graph_objects as go from plotly.subplots import make_subplots import numpy as np import datetime from typing import Dict, List, Optional, Tuple import json from dataclasses import dataclass, asdict import google.generativeai as genai from PIL import Image import pytesseract import keras from huggingface_hub import hf_hub_download import warnings warnings.filterwarnings("ignore") # ============================================================================= # CONFIGURATION FOR HUGGING FACE SPACES # ============================================================================= # Configure Streamlit page st.set_page_config( page_title="đŸĨ MedAI Suite - AI-Powered Medical Platform", page_icon="đŸĨ", layout="wide", initial_sidebar_state="expanded" ) # Get API key from HF Secrets try: GEMINI_API_KEY = st.secrets["GEMINI_API_KEY"] genai.configure(api_key=GEMINI_API_KEY) except: st.error("🔑 Gemini API key not found in secrets. Please configure it in HF Space settings.") st.stop() #Custom CSS def load_custom_css(): st.markdown(""" """, unsafe_allow_html=True) # ============================================================================= # DATA CLASSES # ============================================================================= @dataclass class UserProfile: """Enhanced user medical profile""" user_id: str name: str age: int height: float # cm weight: float # kg sex: str blood_sugar: float # mg/dL blood_pressure: str # systolic/diastolic past_medications: List[str] current_conditions: List[str] allergies: List[str] created_at: str bmi: float = 0.0 def __post_init__(self): if self.height > 0: height_m = self.height / 100 self.bmi = round(self.weight / (height_m ** 2), 2) # ============================================================================= # MEDICAL AI BACKEND # ============================================================================= class MedicalAI: """Complete Medical AI System""" def __init__(self): self.user_profiles = {} self.conversation_history = {} self.gemini_model = None self.dr_model = None self.dr_model_loaded = False # Initialize Gemini self._init_gemini() # Initialize DR model self._init_dr_model() def _init_gemini(self): """Initialize Gemini model""" try: self.gemini_model = genai.GenerativeModel("gemini-2.0-flash") # Don't show success message to avoid clutter except Exception as e: st.error(f"❌ Gemini connection failed: {str(e)}") def _init_dr_model(self): """Initialize diabetic retinopathy model""" try: repo_id = "Arko007/diabetic-retinopathy-v1" weights_filename = "best_model.h5" local_weights_path = hf_hub_download(repo_id=repo_id, filename=weights_filename) self.dr_model = keras.saving.load_model(local_weights_path) self.dr_model_loaded = True except Exception as e: # Silent failure - model will be unavailable but won't show error self.dr_model_loaded = False def validate_user_input(self, user_data: Dict) -> Tuple[bool, List[str]]: """Validate user profile data""" errors = [] required_fields = ['name', 'age', 'height', 'weight', 'sex'] for field in required_fields: if not user_data.get(field): errors.append(f"❌ {field.title()} is required") # Age validation try: age = int(user_data.get('age', 0)) if not 1 <= age <= 150: errors.append("❌ Age must be between 1-150 years") except: errors.append("❌ Age must be a valid number") # Height validation try: height = float(user_data.get('height', 0)) if not 50 <= height <= 300: errors.append("❌ Height must be between 50-300 cm") except: errors.append("❌ Height must be a valid number") # Weight validation try: weight = float(user_data.get('weight', 0)) if not 10 <= weight <= 500: errors.append("❌ Weight must be between 10-500 kg") except: errors.append("❌ Weight must be a valid number") return len(errors) == 0, errors def create_user_profile(self, user_data: Dict) -> Tuple[Optional[UserProfile], List[str]]: """Create new user profile""" is_valid, errors = self.validate_user_input(user_data) if not is_valid: return None, errors timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S') user_id = f"medai_user_{timestamp}" try: profile = UserProfile( user_id=user_id, name=user_data.get('name', '').strip().title(), age=int(user_data.get('age', 0)), height=float(user_data.get('height', 0)), weight=float(user_data.get('weight', 0)), sex=user_data.get('sex', '').lower().strip(), blood_sugar=float(user_data.get('blood_sugar') or 0), blood_pressure=user_data.get('blood_pressure', '').strip(), past_medications=self._clean_list(user_data.get('past_medications', [])), current_conditions=self._clean_list(user_data.get('current_conditions', [])), allergies=self._clean_list(user_data.get('allergies', [])), created_at=datetime.datetime.now().isoformat() ) self.user_profiles[user_id] = profile self.conversation_history[user_id] = [] return profile, [] except Exception as e: return None, [f"❌ Profile creation error: {str(e)}"] def _clean_list(self, input_list) -> List[str]: """Clean list inputs""" if isinstance(input_list, str): return [item.strip() for item in input_list.split(',') if item.strip()] elif isinstance(input_list, list): return [str(item).strip() for item in input_list if str(item).strip()] return [] def get_bmi_category(self, bmi: float) -> str: """Get BMI category""" if bmi < 18.5: return "Underweight" elif bmi < 23: return "Normal weight" elif bmi < 25: return "Overweight" elif bmi < 30: return "Obese Class I" else: return "Obese Class II+" def generate_medical_context(self, user_id: str) -> str: """Generate medical context for consultation""" if user_id not in self.user_profiles: return "" profile = self.user_profiles[user_id] return f""" Patient: {profile.name}, {profile.age} years old, {profile.sex.title()} Physical: Height {profile.height}cm, Weight {profile.weight}kg, BMI {profile.bmi} Vitals: Blood Sugar {profile.blood_sugar} mg/dL, BP {profile.blood_pressure} Medical History: {', '.join(profile.current_conditions) if profile.current_conditions else 'None'} Medications: {', '.join(profile.past_medications) if profile.past_medications else 'None'} Allergies: {', '.join(profile.allergies) if profile.allergies else 'None'} """ def ask_medical_question(self, user_id: str, question: str) -> Dict: """Medical consultation using Gemini""" if not self.gemini_model: return {'success': False, 'error': "AI consultation unavailable"} if user_id not in self.user_profiles: return {'success': False, 'error': "Please create a profile first"} medical_context = self.generate_medical_context(user_id) prompt = f"""You are MedAI, a professional medical AI assistant for healthcare in India. PATIENT CONTEXT: {medical_context} PATIENT QUESTION: {question} INSTRUCTIONS: 1. Provide helpful, evidence-based medical guidance 2. Consider the patient's profile and Indian healthcare context 3. Use clear, supportive language 4. Always emphasize consulting healthcare professionals 5. If urgent symptoms, immediately advise emergency care 6. Keep response comprehensive but accessible (300-400 words) Provide a detailed, caring response that helps the patient understand their health.""" try: response = self.gemini_model.generate_content(prompt) answer = response.text # Store conversation conversation = { 'question': question, 'answer': answer, 'timestamp': datetime.datetime.now().isoformat() } self.conversation_history[user_id].append(conversation) return {'success': True, 'answer': answer, 'timestamp': conversation['timestamp']} except Exception as e: return {'success': False, 'error': f"Consultation error: {str(e)}"} def analyze_medical_report(self, image: Image.Image) -> Dict: """Analyze medical reports using Gemini Vision (no OCR needed)""" if not self.gemini_model: return {'success': False, 'error': "Report analysis unavailable"} try: prompt = f"""You are a medical AI analyzing a healthcare report image for Indian patients. ANALYSIS INSTRUCTIONS: 1. Identify the type of medical report from the image 2. Extract and read all visible text, numbers, and values 3. Highlight values outside normal ranges for Indian population 4. Explain abnormal findings in simple terms with analogies 5. Provide lifestyle recommendations for concerning values 6. Use markdown formatting for clear structure 7. Always end with medical disclaimer Provide a comprehensive, patient-friendly analysis of this medical report image.""" # Use Gemini Vision to analyze image directly response = self.gemini_model.generate_content([prompt, image]) return { 'success': True, 'analysis': response.text, 'extracted_text': "Analysis performed using AI vision - no text extraction needed", 'timestamp': datetime.datetime.now().isoformat() } except Exception as e: return {'success': False, 'error': f"Analysis error: {str(e)}"} def analyze_diabetic_retinopathy(self, image: Image.Image) -> Dict: """Diabetic retinopathy screening using custom model + Gemini explanation""" if not self.dr_model_loaded: return {'success': False, 'error': "Eye screening model unavailable"} try: # Preprocess image img_resized = image.resize((384, 384)) image_array = np.array(img_resized).astype(np.float32) / 255.0 image_array = np.expand_dims(image_array, axis=0) # Get prediction predictions = self.dr_model.predict(image_array, verbose=0) predicted_class_index = np.argmax(predictions, axis=1)[0] confidence = float(np.max(predictions)) class_labels = ["No DR", "Mild DR", "Moderate DR", "Severe DR", "Proliferative DR"] predicted_label = class_labels[predicted_class_index] # Generate detailed analysis if self.gemini_model: prompt = f"""You are an ophthalmology AI providing educational analysis for Indian healthcare. SCREENING RESULT: - AI Classification: {predicted_label} - Model Confidence: {confidence:.2%} - Custom Model: Arko007/diabetic-retinopathy-v1 ANALYSIS INSTRUCTIONS: 1. Explain what this classification means 2. Describe typical changes for this stage 3. Provide follow-up recommendations 4. Include lifestyle guidance 5. Use supportive, clear language 6. Always emphasize this is screening, not diagnosis Provide comprehensive analysis with clear sections.""" try: gemini_response = self.gemini_model.generate_content(prompt) detailed_analysis = gemini_response.text except: detailed_analysis = f"**Classification:** {predicted_label}\n**Confidence:** {confidence:.2%}\n\nPlease consult an eye specialist for detailed evaluation." else: detailed_analysis = f"**Classification:** {predicted_label}\n**Confidence:** {confidence:.2%}" return { 'success': True, 'classification': predicted_label, 'confidence': confidence, 'analysis': detailed_analysis, 'timestamp': datetime.datetime.now().isoformat() } except Exception as e: return {'success': False, 'error': f"Screening error: {str(e)}"} def get_conversation_history(self, user_id: str, limit: int = 10) -> List[Dict]: """Get conversation history""" history = self.conversation_history.get(user_id, []) return history[-limit:] if limit else history # ============================================================================= # SESSION STATE INITIALIZATION # ============================================================================= def initialize_session_state(): """Initialize all session state variables""" if 'medical_ai' not in st.session_state: st.session_state.medical_ai = MedicalAI() if 'current_user' not in st.session_state: st.session_state.current_user = None if 'chat_history' not in st.session_state: st.session_state.chat_history = [] if 'page' not in st.session_state: st.session_state.page = "đŸĨ Dashboard" # ============================================================================= # UI COMPONENTS # ============================================================================= def display_main_header(): """Display main application header""" st.markdown("""

đŸĨ MedAI Suite

AI-Powered Medical Platform | Consultation â€ĸ Report Analysis â€ĸ Eye Screening â€ĸ Health Analytics

""", unsafe_allow_html=True) def create_sidebar(): """Enhanced sidebar navigation""" with st.sidebar: # App branding st.markdown("""

đŸĨ MedAI Suite

Your AI Health Assistant

""", unsafe_allow_html=True) # User info # Replace the user info section in create_sidebar() with this: if st.session_state.current_user: user = st.session_state.current_user st.markdown(f"""

👤 Current Patient

{user.name}
Age: {user.age} | BMI: {user.bmi}

""", unsafe_allow_html=True) if st.button("🔄 New Patient", use_container_width=True): st.session_state.current_user = None st.session_state.chat_history = [] st.rerun() else: st.markdown("""

👤 No Patient Selected

Create a profile to get started

""", unsafe_allow_html=True) # Navigation st.markdown("### 🧭 Navigation") page_options = [ "đŸĨ Dashboard", "👤 Patient Profile", "🤖 Medical Consultation", "📋 Report Analysis", "đŸ‘ī¸ Eye Screening", "📊 Health Analytics" ] selected_page = st.selectbox( "Go to:", page_options, index=page_options.index(st.session_state.page) if st.session_state.page in page_options else 0, key="navigation_selectbox" ) if selected_page != st.session_state.page: st.session_state.page = selected_page st.rerun() # Quick actions st.markdown("### ⚡ Quick Actions") if st.session_state.current_user: if st.button("🚨 Emergency Consultation", use_container_width=True, type="primary"): st.session_state.page = "🤖 Medical Consultation" st.rerun() if st.button("📊 Health Dashboard", use_container_width=True): st.session_state.page = "📊 Health Analytics" st.rerun() # Footer st.markdown("---") st.markdown("""

đŸĨ MedAI Suite
AI-Powered Healthcare Assistant
Made with â¤ī¸ for Better Health

""", unsafe_allow_html=True) def create_patient_profile_form(): """Patient profile creation with FIXED numeric types""" st.markdown("## 👤 Create Patient Profile") with st.form("patient_profile_form", clear_on_submit=False): st.markdown("### Basic Information") col1, col2 = st.columns(2) with col1: name = st.text_input("👤 Full Name*", placeholder="Enter patient name") age = st.number_input("🎂 Age*", min_value=1, max_value=150, value=30, step=1) height = st.number_input("📏 Height (cm)*", min_value=50.0, max_value=300.0, value=170.0, step=1.0) weight = st.number_input("âš–ī¸ Weight (kg)*", min_value=10.0, max_value=300.0, value=70.0, step=0.1) with col2: sex = st.selectbox("⚧ Sex*", ["Male", "Female", "Other"], key="sex_selectbox") blood_sugar = st.number_input("đŸŦ Blood Sugar (mg/dL)", min_value=0.0, value=95.0, step=1.0) # Blood pressure - FIXED st.markdown("đŸŠē **Blood Pressure**") bp_col1, bp_col2 = st.columns(2) with bp_col1: bp_sys = st.number_input("Systolic", min_value=60, max_value=250, value=120, step=1, key="bp_sys") with bp_col2: bp_dia = st.number_input("Diastolic", min_value=40, max_value=150, value=80, step=1, key="bp_dia") st.markdown("### Medical History (Optional)") col3, col4 = st.columns(2) with col3: conditions = st.text_area("đŸĨ Current Conditions", placeholder="e.g., Diabetes, Hypertension (comma-separated)") medications = st.text_area("💊 Past Medications", placeholder="e.g., Metformin, Aspirin (comma-separated)") with col4: allergies = st.text_area("âš ī¸ Known Allergies", placeholder="e.g., Penicillin, Shellfish (comma-separated)") notes = st.text_area("📝 Additional Notes", placeholder="Any other relevant information") # FIXED - Submit button added submitted = st.form_submit_button("✅ Create Profile", type="primary", use_container_width=True) if submitted and name and age and height and weight and sex: user_data = { 'name': name, 'age': age, 'height': height, 'weight': weight, 'sex': sex.lower(), 'blood_sugar': blood_sugar, 'blood_pressure': f"{bp_sys}/{bp_dia}", 'current_conditions': conditions, 'past_medications': medications, 'allergies': allergies } profile, errors = st.session_state.medical_ai.create_user_profile(user_data) if profile: st.session_state.current_user = profile st.markdown(f"""

✅ Profile Created Successfully!

Welcome {name}! Your medical profile is ready.

""", unsafe_allow_html=True) st.balloons() st.rerun() else: for error in errors: st.error(error) def display_patient_profile(): """Display patient profile dashboard""" if not st.session_state.current_user: return user = st.session_state.current_user # Profile header st.markdown(f"""

👤 {user.name}

Patient ID: {user.user_id} | Created: {user.created_at[:10]}

""", unsafe_allow_html=True) # Metrics col1, col2, col3, col4, col5, col6 = st.columns(6) metrics = [ (col1, "Age", f"{user.age}", "years"), (col2, "Height", f"{user.height}", "cm"), (col3, "Weight", f"{user.weight}", "kg"), (col4, "BMI", f"{user.bmi}", st.session_state.medical_ai.get_bmi_category(user.bmi)), (col5, "Blood Sugar", f"{user.blood_sugar}", "mg/dL"), (col6, "Blood Pressure", user.blood_pressure, "mmHg") ] for col, title, value, unit in metrics: with col: st.markdown(f"""

{title}

{value}

{unit}
""", unsafe_allow_html=True) # Medical history if any([user.current_conditions, user.past_medications, user.allergies]): st.markdown("### 📋 Medical Summary") col1, col2, col3 = st.columns(3) with col1: st.markdown("**đŸĨ Current Conditions**") if user.current_conditions: for condition in user.current_conditions: st.markdown(f"â€ĸ {condition}") else: st.markdown("â€ĸ None reported") with col2: st.markdown("**💊 Past Medications**") if user.past_medications: for medication in user.past_medications: st.markdown(f"â€ĸ {medication}") else: st.markdown("â€ĸ None reported") with col3: st.markdown("**âš ī¸ Known Allergies**") if user.allergies: for allergy in user.allergies: st.markdown(f"â€ĸ {allergy}") else: st.markdown("â€ĸ None reported") def create_medical_consultation(): """AI Medical Consultation Interface""" st.markdown("## 🤖 AI Medical Consultation") if not st.session_state.current_user: st.markdown("""

âš ī¸ Patient Profile Required

Please create a patient profile first to receive personalized medical consultation.

""", unsafe_allow_html=True) return user = st.session_state.current_user # Patient context with st.expander("👤 Current Patient Context", expanded=False): col1, col2 = st.columns(2) with col1: st.write(f"**Name:** {user.name}") st.write(f"**Age:** {user.age} years") st.write(f"**BMI:** {user.bmi} ({st.session_state.medical_ai.get_bmi_category(user.bmi)})") with col2: st.write(f"**Blood Sugar:** {user.blood_sugar} mg/dL") st.write(f"**Blood Pressure:** {user.blood_pressure}") if user.current_conditions: st.write(f"**Conditions:** {', '.join(user.current_conditions)}") # Quick consultation topics st.markdown("#### 🔍 Quick Consultation Topics") col1, col2, col3, col4 = st.columns(4) quick_topics = [ ("📊 Health Review", "Please review my current health metrics and provide insights."), ("đŸŠē Blood Pressure", "What should I know about managing my blood pressure?"), ("🍎 Lifestyle Tips", "What lifestyle changes would you recommend for me?"), ("âš ī¸ Risk Assessment", "Are there any health risks I should be aware of?") ] selected_topic = None for i, (col, (title, question)) in enumerate(zip([col1, col2, col3, col4], quick_topics)): with col: if st.button(title, use_container_width=True, key=f"topic_{i}"): selected_topic = question # Chat interface st.markdown("### đŸ’Ŧ Ask Your Medical Questions") # Display chat history for msg in st.session_state.chat_history[-5:]: # Show last 5 messages if msg["role"] == "user": st.markdown(f"""
👤 You: {msg["content"]}
""", unsafe_allow_html=True) else: st.markdown(f"""
🤖 MedAI: {msg["content"]}
""", unsafe_allow_html=True) # Input form - FIXED with submit button with st.form("medical_consultation_form", clear_on_submit=True): question = st.text_area( "âœī¸ Your Medical Question:", value=selected_topic if selected_topic else "", placeholder="Describe your symptoms or ask about your health...", height=100 ) col1, col2 = st.columns([3, 1]) with col1: priority = st.selectbox("🚨 Priority Level", ["Normal", "Urgent", "Emergency"], key="priority_selectbox") submitted = st.form_submit_button("🤖 Get AI Consultation", type="primary", use_container_width=True) if submitted and question.strip(): # Add user message st.session_state.chat_history.append({"role": "user", "content": question}) # Emergency check if priority == "Emergency" or any(word in question.lower() for word in ['chest pain', "can't breathe", 'severe pain', 'bleeding']): st.markdown("""

🚨 MEDICAL EMERGENCY ALERT

If this is a medical emergency, please call emergency services immediately (102/108) or visit the nearest hospital!

""", unsafe_allow_html=True) # Get AI response with st.spinner("🧠 MedAI is analyzing your question..."): response = st.session_state.medical_ai.ask_medical_question(user.user_id, question) if response['success']: # Add AI response st.session_state.chat_history.append({"role": "assistant", "content": response['answer']}) st.rerun() else: st.error(f"❌ Consultation error: {response['error']}") # Medical disclaimer st.markdown("""

âš ī¸ IMPORTANT MEDICAL DISCLAIMER

This AI assistant provides general health information for educational purposes only. It is not a substitute for professional medical advice, diagnosis, or treatment. Always consult qualified healthcare professionals for medical concerns.

""", unsafe_allow_html=True) def create_report_analysis(): """Medical Report Analysis Interface""" st.markdown("## 📋 Medical Report Analysis") st.markdown("""

đŸ”Ŧ AI-Powered Report Analysis

Upload images of your medical reports for AI analysis. Supports blood tests, urine tests, lipid profiles, liver function tests, kidney function tests, and more.

Supported formats: PNG, JPG, JPEG

""", unsafe_allow_html=True) # File upload uploaded_file = st.file_uploader( "📁 Choose Medical Report Image", type=['png', 'jpg', 'jpeg'], help="Upload a clear image of your medical report" ) if uploaded_file: image = Image.open(uploaded_file) col1, col2 = st.columns([1, 1]) with col1: st.markdown("### 📷 Uploaded Report") st.image(image, caption="Your medical report", use_column_width=True) # Image quality check width, height = image.size if width < 800 or height < 600: st.warning("âš ī¸ Low resolution detected. Higher resolution images provide better analysis.") with col2: if st.button("🔍 Analyze Report", type="primary", use_container_width=True): with st.spinner("🧠 Analyzing your medical report..."): result = st.session_state.medical_ai.analyze_medical_report(image) if result['success']: st.markdown("### 📊 AI Analysis Results") st.markdown(result['analysis']) # Show extracted text with st.expander("📝 Extracted Text Preview", expanded=False): st.text(result.get('extracted_text', 'Text extraction unavailable')) if st.session_state.current_user: st.success("✅ Analysis complete! Results ready for consultation.") else: st.error(f"❌ Analysis failed: {result['error']}") # Tips for better results with st.expander("💡 Tips for Better Analysis", expanded=False): st.markdown(""" **For optimal results:** 1. **📸 Clear Image:** Ensure good lighting and sharp text 2. **📐 Straight Orientation:** Keep the report upright 3. **🔍 High Resolution:** Use at least 800x600 pixels 4. **📋 Complete Report:** Include all sections and reference ranges 5. **đŸĨ Official Reports:** Use certified laboratory reports **Supported Report Types:** - Complete Blood Count (CBC) - Blood Chemistry Panels - Lipid Profiles - Liver & Kidney Function Tests - Thyroid Function Tests - Diabetes Monitoring (HbA1c, Glucose) """) def create_diabetic_retinopathy_screening(): """Diabetic Retinopathy Screening Interface""" st.markdown("## đŸ‘ī¸ AI Eye Screening") if not st.session_state.medical_ai.dr_model_loaded: st.markdown("""

❌ Eye Screening Unavailable

The diabetic retinopathy screening model could not be loaded. Please try refreshing the page.

""", unsafe_allow_html=True) return st.markdown("""

đŸ”Ŧ AI-Powered Diabetic Retinopathy Screening

Upload retinal fundus images for AI screening of diabetic retinopathy. Our custom deep learning model can detect signs of eye complications in diabetic patients.

Model: Arko007/diabetic-retinopathy-v1 (Custom trained for Indian population)

""", unsafe_allow_html=True) # Upload interface uploaded_image = st.file_uploader( "📁 Upload Retinal Fundus Image", type=['png', 'jpg', 'jpeg'], help="Upload a clear retinal photograph", key="dr_image_upload" ) if uploaded_image: image = Image.open(uploaded_image) col1, col2 = st.columns([1, 1]) with col1: st.markdown("### đŸ‘ī¸ Retinal Image") st.image(image, caption="Retinal fundus image", use_column_width=True) # Image info width, height = image.size st.info(f"📏 Image dimensions: {width}×{height} pixels") if width < 384 or height < 384: st.warning("âš ī¸ Minimum recommended resolution: 384×384 pixels") with col2: if st.button("🔍 Screen for Diabetic Retinopathy", type="primary", use_container_width=True): with st.spinner("🧠 AI is analyzing the retinal image..."): result = st.session_state.medical_ai.analyze_diabetic_retinopathy(image) if result['success']: classification = result['classification'] confidence = result['confidence'] # Severity color coding severity_colors = { "No DR": "đŸŸĸ", "Mild DR": "🟡", "Moderate DR": "🟠", "Severe DR": "🔴", "Proliferative DR": "🔴" } color = severity_colors.get(classification, "âšĒ") st.markdown(f"""

{color} AI Screening Result: {classification}

Model Confidence: {confidence:.1%}

""", unsafe_allow_html=True) # Confidence bar st.progress(confidence) # Detailed analysis st.markdown("### 📊 Detailed Analysis") st.markdown(result['analysis']) # Recommendations st.markdown("### 💡 Recommendations") if classification == "No DR": st.success("✅ No diabetic retinopathy detected. Continue regular eye checkups.") elif classification == "Mild DR": st.warning("âš ī¸ Mild diabetic retinopathy detected. Schedule follow-up in 6-12 months.") elif classification in ["Moderate DR", "Severe DR"]: st.error("🔴 Significant diabetic retinopathy detected. Consult an ophthalmologist promptly.") elif classification == "Proliferative DR": st.error("🚨 Advanced diabetic retinopathy detected. URGENT ophthalmologist consultation required!") if st.session_state.current_user: st.info("💾 Screening results saved to your profile.") else: st.error(f"❌ Screening failed: {result['error']}") # Educational information st.markdown("### 📚 Understanding Diabetic Retinopathy") with st.expander("â„šī¸ About Diabetic Retinopathy", expanded=False): st.markdown(""" **What is Diabetic Retinopathy?** A diabetes complication affecting the eyes, caused by damage to retinal blood vessels. **Screening Stages:** 1. **đŸŸĸ No DR:** No signs detected 2. **🟡 Mild DR:** Early changes (microaneurysms) 3. **🟠 Moderate DR:** Blood vessels become blocked 4. **🔴 Severe DR:** Significant blood vessel blockage 5. **🔴 Proliferative DR:** Advanced stage with new vessel growth **Risk Factors:** - Duration of diabetes - Poor blood sugar control - High blood pressure - Pregnancy in diabetic women **Prevention:** - Maintain good blood sugar control - Regular eye examinations - Control blood pressure and cholesterol - Healthy lifestyle choices """) # Screening disclaimer st.markdown("""

âš ī¸ SCREENING DISCLAIMER

This AI screening tool is for educational purposes only. It is not a medical device and cannot replace professional eye examination. Always consult qualified ophthalmologists for proper diagnosis and treatment of eye conditions.

""", unsafe_allow_html=True) def generate_health_metrics(profile_data=None, days=30): """Generate sample health data for analytics""" dates = pd.date_range(start=datetime.date.today() - datetime.timedelta(days=days), periods=days, freq='D') # Base values from profile if profile_data: base_weight = profile_data.weight base_sugar = profile_data.blood_sugar if profile_data.blood_sugar > 0 else 95 bp_parts = profile_data.blood_pressure.split('/') base_bp_sys = float(bp_parts[0]) if len(bp_parts) == 2 else 120 base_bp_dia = float(bp_parts[1]) if len(bp_parts) == 2 else 80 else: base_weight, base_sugar, base_bp_sys, base_bp_dia = 70, 95, 120, 80 # Generate realistic variations np.random.seed(42) weight = np.random.normal(base_weight, 0.5, days) blood_sugar = np.clip(np.random.normal(base_sugar, 10, days), 70, 300) bp_systolic = np.clip(np.random.normal(base_bp_sys, 8, days), 90, 180) bp_diastolic = np.clip(np.random.normal(base_bp_dia, 5, days), 60, 120) steps = np.maximum(2000, np.random.normal(8000, 1500, days)).astype(int) sleep_hours = np.clip(np.random.normal(7.5, 1, days), 5, 10) return pd.DataFrame({ 'date': dates, 'weight': weight.round(1), 'blood_sugar': blood_sugar.round(0), 'bp_systolic': bp_systolic.round(0), 'bp_diastolic': bp_diastolic.round(0), 'steps': steps, 'sleep_hours': sleep_hours.round(1) }) def create_health_analytics(): """Health Analytics Dashboard""" st.markdown("## 📊 Health Analytics Dashboard") if not st.session_state.current_user: st.markdown("""

âš ī¸ Patient Profile Required

Create a patient profile to view personalized health analytics.

""", unsafe_allow_html=True) return user = st.session_state.current_user health_data = generate_health_metrics(user) # Health score calculation bmi_score = 25 if 18.5 <= user.bmi <= 25 else 15 sugar_score = 25 if user.blood_sugar <= 100 else 15 bp_parts = user.blood_pressure.split('/') bp_score = 25 if len(bp_parts) == 2 and int(bp_parts[0]) <= 120 and int(bp_parts[1]) <= 80 else 15 activity_score = 25 # Assume good activity total_score = bmi_score + sugar_score + bp_score + activity_score # Dashboard tabs tab1, tab2, tab3 = st.tabs(["📈 Overview", "📊 Detailed Metrics", "đŸŽ¯ Health Score"]) with tab1: st.subheader("📊 Health Overview") # Key metrics col1, col2, col3, col4 = st.columns(4) latest = health_data.iloc[-1] with col1: st.metric("Current Weight", f"{latest['weight']:.1f} kg", delta=f"{latest['weight'] - health_data['weight'].mean():+.1f}") with col2: st.metric("Blood Sugar", f"{latest['blood_sugar']:.0f} mg/dL", delta=f"{latest['blood_sugar'] - health_data['blood_sugar'].mean():+.0f}") with col3: st.metric("Blood Pressure", f"{latest['bp_systolic']:.0f}/{latest['bp_diastolic']:.0f}", help="Systolic/Diastolic pressure in mmHg") with col4: st.metric("Daily Steps", f"{latest['steps']:,}", delta=f"{latest['steps'] - health_data['steps'].mean():+,.0f}") # Trends chart fig = make_subplots( rows=2, cols=2, subplot_titles=('Weight Trend', 'Blood Sugar', 'Blood Pressure', 'Activity'), specs=[[{"secondary_y": False}, {"secondary_y": False}], [{"secondary_y": False}, {"secondary_y": False}]] ) fig.add_trace(go.Scatter(x=health_data['date'], y=health_data['weight'], name='Weight', line=dict(color='#2E8B57')), row=1, col=1) fig.add_trace(go.Scatter(x=health_data['date'], y=health_data['blood_sugar'], name='Blood Sugar', line=dict(color='#DC143C')), row=1, col=2) fig.add_trace(go.Scatter(x=health_data['date'], y=health_data['bp_systolic'], name='Systolic', line=dict(color='#FF8C00')), row=2, col=1) fig.add_trace(go.Scatter(x=health_data['date'], y=health_data['steps'], name='Steps', line=dict(color='#32CD32')), row=2, col=2) fig.update_layout(height=600, showlegend=False, title_text="30-Day Health Trends") st.plotly_chart(fig, use_container_width=True) with tab2: st.subheader("📈 Detailed Health Metrics") # Data table st.markdown("#### Recent Health Records") display_data = health_data.tail(7).copy() display_data['date'] = display_data['date'].dt.strftime('%Y-%m-%d') st.dataframe(display_data, use_container_width=True) # Correlation analysis st.markdown("#### Health Metrics Correlation") corr_data = health_data[['weight', 'blood_sugar', 'bp_systolic', 'steps', 'sleep_hours']].corr() fig_corr = px.imshow(corr_data, title="Health Metrics Correlation Matrix", color_continuous_scale='RdBu_r', aspect="auto") st.plotly_chart(fig_corr, use_container_width=True) with tab3: st.subheader("đŸŽ¯ Personal Health Score") # Health score gauge fig_gauge = go.Figure(go.Indicator( mode="gauge+number", value=total_score, domain={'x': [0, 1], 'y': [0, 1]}, title={'text': "Overall Health Score"}, gauge={ 'axis': {'range': [None, 100]}, 'bar': {'color': "#2E8B57"}, 'steps': [ {'range': [0, 60], 'color': "lightgray"}, {'range': [60, 80], 'color': "yellow"}, {'range': [80, 100], 'color': "#32CD32"} ], 'threshold': { 'line': {'color': "red", 'width': 4}, 'thickness': 0.75, 'value': 90 } } )) st.plotly_chart(fig_gauge, use_container_width=True) # Score breakdown col1, col2, col3, col4 = st.columns(4) with col1: st.metric("BMI Score", f"{bmi_score}/25") with col2: st.metric("Blood Sugar Score", f"{sugar_score}/25") with col3: st.metric("Blood Pressure Score", f"{bp_score}/25") with col4: st.metric("Activity Score", f"{activity_score}/25") # Recommendations st.markdown("### 💡 Personalized Health Recommendations") recommendations = [] if bmi_score < 25: recommendations.append("đŸ‹ī¸ Focus on achieving a healthy BMI through balanced nutrition and exercise") if sugar_score < 25: recommendations.append("🍎 Monitor blood sugar levels and consider dietary adjustments") if bp_score < 25: recommendations.append("đŸŠē Keep track of blood pressure and practice stress management") if not recommendations: recommendations.append("🎉 Excellent health metrics! Continue your healthy lifestyle.") for rec in recommendations: st.success(rec) def create_dashboard_home(): """Main dashboard home page""" display_main_header() if not st.session_state.current_user: # Welcome screen st.markdown("## 🌟 Welcome to MedAI Suite") col1, col2 = st.columns([2, 1]) with col1: st.markdown("""

🚀 Your AI-Powered Health Platform

Get started with comprehensive healthcare AI tools:

👤 Create your patient profile to begin!

""", unsafe_allow_html=True) with col2: st.markdown("### đŸŽ¯ Quick Start") if st.button("👤 Create Patient Profile", use_container_width=True, type="primary"): st.session_state.page = "👤 Patient Profile" st.rerun() st.markdown("### 🔧 System Status") status_items = [ ("🤖 AI Consultation", "Ready"), ("📋 Report Analysis", "Ready"), ("đŸ‘ī¸ Eye Screening", "Ready" if st.session_state.medical_ai.dr_model_loaded else "Loading"), ("📊 Health Analytics", "Ready") ] for item, status in status_items: color = "đŸŸĸ" if status == "Ready" else "🟡" st.markdown(f"{color} {item}: {status}") # Feature showcase st.markdown("## đŸĨ Platform Features") col1, col2, col3, col4 = st.columns(4) features = [ ("🤖", "AI Consultation", "Get personalized medical advice"), ("📋", "Report Analysis", "Understand your medical reports"), ("đŸ‘ī¸", "Eye Screening", "Detect diabetic retinopathy"), ("📊", "Health Analytics", "Track your health progress") ] for col, (icon, title, desc) in zip([col1, col2, col3, col4], features): with col: st.markdown(f"""

{icon}

{title}

{desc}

""", unsafe_allow_html=True) else: # User dashboard user = st.session_state.current_user st.markdown(f"## 👋 Welcome back, {user.name}!") # Quick stats col1, col2, col3, col4 = st.columns(4) consultations = len(st.session_state.medical_ai.get_conversation_history(user.user_id)) days_active = (datetime.datetime.now() - datetime.datetime.fromisoformat(user.created_at)).days with col1: st.metric("đŸ’Ŧ Consultations", consultations) with col2: st.metric("📅 Days Active", days_active) with col3: st.metric("đŸŽ¯ Health Score", "85/100") with col4: st.metric("âš–ī¸ BMI Status", st.session_state.medical_ai.get_bmi_category(user.bmi)) # Quick actions st.markdown("### ⚡ Quick Actions") col1, col2, col3, col4 = st.columns(4) action_buttons = [ ("🤖 AI Consultation", "🤖 Medical Consultation"), ("📋 Analyze Report", "📋 Report Analysis"), ("đŸ‘ī¸ Eye Screening", "đŸ‘ī¸ Eye Screening"), ("📊 Health Dashboard", "📊 Health Analytics") ] for col, (title, page) in zip([col1, col2, col3, col4], action_buttons): with col: if st.button(title, use_container_width=True): st.session_state.page = page st.rerun() # Recent activity st.markdown("### 📋 Recent Activity") recent_history = st.session_state.medical_ai.get_conversation_history(user.user_id, limit=3) if recent_history: for i, conv in enumerate(recent_history[::-1], 1): with st.expander(f"đŸ’Ŧ Consultation {i} - {conv['timestamp'][:16]}"): st.markdown(f"**Question:** {conv['question'][:150]}...") st.markdown(f"**Response:** {conv['answer'][:200]}...") else: st.info("🔍 No consultations yet. Start your first AI consultation!") # ============================================================================= # MAIN APPLICATION LOGIC # ============================================================================= def main(): """Main application entry point""" # Load custom CSS load_custom_css() # Initialize session state initialize_session_state() # Create sidebar create_sidebar() # Route to appropriate page page = st.session_state.page if page == "đŸĨ Dashboard": create_dashboard_home() elif page == "👤 Patient Profile": if st.session_state.current_user: display_patient_profile() st.markdown("---") if st.button("âœī¸ Create New Profile", type="secondary"): st.session_state.current_user = None st.session_state.chat_history = [] st.rerun() else: create_patient_profile_form() elif page == "🤖 Medical Consultation": create_medical_consultation() elif page == "📋 Report Analysis": create_report_analysis() elif page == "đŸ‘ī¸ Eye Screening": create_diabetic_retinopathy_screening() elif page == "📊 Health Analytics": create_health_analytics() else: create_dashboard_home() # ============================================================================= # APPLICATION ENTRY POINT # ============================================================================= if __name__ == "__main__": main()