File size: 12,823 Bytes
3c8615e f24d56c 3c8615e 25784c4 8b43d60 0381fad 3c8615e fec880a 52402fd fec880a 2df62ed 5af845c 52402fd fec880a 97336a8 fec880a 97336a8 2df62ed a3c17fa 2df62ed 5b940aa 92fe3f1 13af3e0 156466a 13af3e0 8468201 8b43d60 e6c7b55 8468201 156466a ab43899 156466a 8468201 c2241c4 8b43d60 8468201 3934b8b 8468201 3934b8b 8468201 3934b8b 8468201 3934b8b 8468201 1737776 ab43899 1737776 c2241c4 1737776 8b43d60 ffcdcc7 8b43d60 ffcdcc7 eef2ede 8b43d60 8468201 0ca0958 e6c7b55 0ca0958 c2241c4 0ca0958 0381fad c2241c4 0381fad c2241c4 0381fad eef2ede c2241c4 0ca0958 09c7128 0ca0958 8468201 8b43d60 1737776 156466a e6c7b55 0ca0958 e6c7b55 156466a eef2ede c2241c4 09c7128 eef2ede c2241c4 eef2ede c2241c4 eef2ede 0381fad eef2ede 0381fad c2241c4 0381fad 09c7128 eef2ede 09c7128 eef2ede 0381fad 09c7128 13af3e0 8468201 a903ab2 b284c02 | 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 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | # app.py
import gradio as gr
from components.auth import register, login, logout
from components.predict import predict
from components.report_generator import create_report
from components.diabetes_factors import render_factors_info
from components.food_suggestions import render_food_guide
from components.doctor_info import render_doctor_list
from components.how_to_use import render_how_to_use_guide
# --- Style and Theme with FINAL Mobile-Responsive CSS ---
css = """
/* --- CRITICAL FIX FOR SCROLLING ON MOBILE --- */
/* This forces the entire page to allow vertical scrolling and grow with its content */
html, body {
overflow-y: auto !important; /* Allow vertical scrolling! */
height: auto !important; /* Let the body grow beyond the screen height */
}
/* General container style for all screens */
.gradio-container { max-width: 1000px !important; margin: auto !important; }
.centered-text { text-align: center; }
/* Fix for invisible button text in dark mode */
.gradio-button.primary, .gradio-button.secondary {
color: white !important;
}
/* Responsive rules for stacking content WITHIN the app */
@media (max-width: 768px) {
.gradio-row {
flex-direction: column !important;
gap: 1rem !important;
}
.gradio-row > * {
width: 100% !important;
min-width: unset !important;
margin: 0 !important;
}
}
"""
with gr.Blocks(title="DiaSpark: Your Health Management Platform", css=css) as demo:
user_state = gr.State({"email": None, "id": None, "logged_in": False, "gender": None, "username": None})
# --- Static Header (Always Visible) ---
gr.Markdown("# π©Ί Welcome to DiaSpark: Your Health Management Platform")
# --- Personalized Header (Visible only when logged in) ---
with gr.Row(visible=False) as logged_in_header:
welcome_message = gr.Markdown()
# --- Main Tabs ---
with gr.Tabs() as main_tabs:
# --- Tab 1: Homepage ---
with gr.TabItem("Home π ", id="home_tab"):
gr.Markdown(
"<h2 class='centered-text'>A Smart First Step in Understanding Your Health</h2>",
elem_classes="centered-text"
)
gr.Markdown(
"""
DiaSpark is a confidential tool that uses machine learning to provide an educational analysis of your diabetes risk factors.
Our goal is to promote health awareness, not to provide a medical diagnosis.
"""
)
gr.Markdown("---")
with gr.Accordion("π― Our Mission: The 'Why'", open=True):
gr.Markdown(
"""
We believe that awareness is the first and most powerful step towards a healthier life.
This tool was built to help you:
* **Gain Insight:** Understand how key health metrics can contribute to your overall risk profile.
* **Encourage Proactive Care:** Use this information as a starting point for meaningful conversations with your doctor.
* **Do It All Privately:** Your health data is sensitive. Our secure login ensures your prediction history is for your eyes only.
"""
)
with gr.Accordion("π Getting Started: The 'How'", open=False):
gr.Markdown(
"""
1. **Create Your Secure Account:** Navigate to the **'Login / Signup'** tab. The process is quick and requires a username, email, password, and gender.
2. **Enter Your Health Metrics:** Once logged in, go to the **'Prediction'** tab. Fill in the fields with your most recent health information.
3. **Receive Your Instant Analysis:** Click the 'Predict My Risk' button. Our AI model will provide an immediate, educational assessment based on your data.
"""
)
with gr.Accordion("β οΈ Important Disclaimer", open=False):
gr.Markdown(
"""
**This tool is NOT a substitute for professional medical advice, diagnosis, or treatment.**
The results from DiaSpark are for informational purposes only. Always seek the advice of your physician or another qualified health provider with any questions you may have regarding a medical condition. Never disregard professional medical advice or delay in seeking it because of something you have read or seen on this application.
"""
)
# --- Tab 2: Authentication ---
with gr.TabItem("Login / Signup π", id="auth_tab") as auth_tab_item:
auth_message = gr.Markdown()
with gr.Column(visible=True) as login_col:
gr.Markdown("### Login to Your Account")
email_login = gr.Textbox(label="Email", placeholder="Enter your email")
pwd_login = gr.Textbox(label="Password", type="password", placeholder="Enter your password")
login_btn = gr.Button("Login", variant="primary")
show_signup_btn = gr.Button("New user? Sign up here.", variant="secondary")
with gr.Column(visible=False) as signup_col:
gr.Markdown("### Create a New Account")
username_signup = gr.Textbox(label="Username", placeholder="Choose a unique username")
email_signup = gr.Textbox(label="Email", placeholder="Enter your email")
pwd_signup = gr.Textbox(
label="Password",
type="password",
placeholder="Create a password",
info="Must be at least 6 characters long."
)
gender_signup = gr.Radio(["Female", "Male"], label="Gender", info="This determines if the 'Pregnancies' field is shown.")
signup_btn = gr.Button("Sign Up", variant="primary")
show_login_btn = gr.Button("Already have an account? Login.", variant="secondary")
# --- NEW "How to Use" Tab ---
with gr.TabItem("How to Use π‘"):
render_how_to_use_guide()
# --- The rest of the informational and tool tabs ---
with gr.TabItem("Learn About Diabetes π"):
render_factors_info()
with gr.TabItem("Healthy Eating Guide π₯"):
render_food_guide()
with gr.TabItem("Find a Specialist π§ββοΈ"):
render_doctor_list()
# --- Prediction Tab ---
with gr.TabItem("Prediction Tool π¬", id="prediction_tab"):
with gr.Column(visible=False) as prediction_view:
gr.Markdown("### Enter Your Health Metrics for Prediction")
gr.Markdown("---")
with gr.Row(visible=False) as pregnancies_row:
preg = gr.Number(label="Pregnancies", info="Number of times pregnant")
with gr.Row():
with gr.Column(scale=2):
glucose = gr.Number(label="Glucose", info="Plasma glucose concentration (mg/dL)")
bp = gr.Number(label="Blood Pressure", info="Diastolic (bottom number, mm Hg)")
insulin = gr.Number(label="Insulin", info="2-Hour serum insulin (mu U/ml)")
age = gr.Number(label="Age", info="Age in years")
with gr.Column(scale=1):
bmi = gr.Number(label="BMI", info="Your Body Mass Index. We can calculate this for you.")
bmi_choice = gr.Radio(
["I know my BMI", "Calculate from Weight/Height"],
label="Provide BMI",
value="I know my BMI"
)
with gr.Column(visible=False) as bmi_calc_view:
weight = gr.Number(label="Your Weight (kg)")
height = gr.Number(label="Your Height (cm)")
with gr.Row():
predict_btn = gr.Button("Predict My Risk", variant="primary")
result_output = gr.Textbox(label="Prediction Result", interactive=False)
generate_report_btn = gr.Button("Download Report as PDF", variant="secondary", visible=False)
report_file_output = gr.File(label="Your Report", visible=False)
logout_btn = gr.Button("Logout", variant="stop")
with gr.Column(visible=True) as logged_out_view:
gr.Markdown(
"""
<div style="text-align:center; padding: 50px;">
<h2>π Please log in to access the prediction tool.</h2>
<p>You can create an account or log in via the 'Login / Signup' tab.</p>
</div>
"""
)
# --- Component Logic (Event Handlers) ---
def switch_to_signup(): return gr.update(visible=False), gr.update(visible=True)
def switch_to_login(): return gr.update(visible=True), gr.update(visible=False)
show_signup_btn.click(fn=switch_to_signup, outputs=[login_col, signup_col])
show_login_btn.click(fn=switch_to_login, outputs=[login_col, signup_col])
def handle_user_state_change(user_data):
is_logged_in = user_data.get("logged_in", False)
is_female = user_data.get("gender") == "Female"
username = user_data.get("username", "User")
welcome_text = f"### π Welcome, {username}!"
return (gr.update(visible=is_logged_in), gr.update(visible=not is_logged_in), gr.update(visible=is_female), gr.update(value=welcome_text), gr.update(visible=is_logged_in), gr.update(visible=not is_logged_in))
user_state.change(fn=handle_user_state_change, inputs=user_state, outputs=[prediction_view, logged_out_view, pregnancies_row, welcome_message, logged_in_header, auth_tab_item])
signup_btn.click(fn=register, inputs=[email_signup, pwd_signup, gender_signup, username_signup], outputs=[auth_message, email_signup, pwd_signup, gender_signup, username_signup])
login_btn.click(fn=login, inputs=[email_login, pwd_login, user_state], outputs=[auth_message, user_state, main_tabs])
# The logout handler must now also clear the weight and height fields.
logout_btn.click(fn=logout, inputs=[user_state], outputs=[auth_message, user_state, main_tabs, email_login, pwd_login, preg, glucose, bp, insulin, bmi, age, result_output, pregnancies_row, weight, height, bmi_choice])
# --- CORRECTED BMI LOGIC ---
def toggle_bmi_inputs(choice):
if choice == "I know my BMI":
# Return 4 values: one for each output component
return gr.update(interactive=True, value=None), None, None, gr.update(visible=False)
else: # Calculate from Weight/Height
# Also return 4 values here to match the outputs list
return gr.update(interactive=False, value=None), gr.update(), gr.update(), gr.update(visible=True)
bmi_choice.change(fn=toggle_bmi_inputs, inputs=bmi_choice, outputs=[bmi, weight, height, bmi_calc_view])
def calculate_bmi(w, h):
if w and h and w > 0 and h > 0:
bmi_val = round(w / ((h / 100) ** 2), 2)
return bmi_val
return None
weight.change(fn=calculate_bmi, inputs=[weight, height], outputs=bmi)
height.change(fn=calculate_bmi, inputs=[weight, height], outputs=bmi)
predict_btn.click(fn=predict, inputs=[preg, glucose, bp, insulin, bmi, age, user_state], outputs=[result_output])
def handle_create_report(user, p, g, b, i, bmi_val, age_val, result):
if not result:
return gr.update(visible=False)
# Recalculate is no longer needed, just use the value from the bmi box
final_bmi_report = bmi_val if bmi_val is not None else 0
input_data = {"Pregnancies": p if p is not None else 0, "Glucose": g, "Blood Pressure": b, "Insulin": i, "BMI": final_bmi_report, "Age": age_val}
file_path = create_report(user, input_data, result)
# CORRECTED TYPO: It should be 'file_path', not 'file_file'
return gr.update(value=file_path, visible=True)
generate_report_btn.click(fn=handle_create_report, inputs=[user_state, preg, glucose, bp, insulin, bmi, age, result_output], outputs=[report_file_output])
result_output.change(fn=lambda x: gr.update(visible=bool(x)), inputs=result_output, outputs=generate_report_btn)
# --- Launch the App ---
if __name__ == "__main__":
demo.launch() |