ALYYAN commited on
Commit
7cc9990
·
unverified ·
1 Parent(s): 22352ad

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -38
app.py CHANGED
@@ -1,10 +1,12 @@
 
 
1
  import gradio as gr
2
  from pathlib import Path
3
  import asyncio
4
 
5
  # Import backend components
6
  from app.prediction import PredictionPipeline
7
- from app.database import add_patient_record, get_all_records
8
 
9
  # --- Initialization ---
10
  prediction_pipeline = PredictionPipeline()
@@ -35,16 +37,15 @@ async def refresh_history_table():
35
  # --- Gradio UI Definition ---
36
  css = """
37
  /* --- Professional Dark Theme & Fonts --- */
38
- :root { --primary-hue: 220 !important; --secondary-hue: 210 !important; --neutral-hue: 210 !important; --body-background-fill: #111827 !important; --block-background-fill: #1F2937 !important; --block-border-width: 1px !important; --border-color-accent: #374151 !important; --background-fill-secondary: #1F2937 !important;}
39
- /* --- Header & Title Styling --- */
40
  #app_header { text-align: center; max-width: 900px; margin: 0 auto; }
41
- #app_title { font-size: 2.8rem !important; font-weight: 700 !important; color: #FFFFFF !important; padding-top: 1rem; }
42
- #app_subtitle { font-size: 1.2rem !important; color: #9CA3AF !important; margin-bottom: 2rem; }
43
  /* --- Layout and Spacing --- */
44
- #main_container { gap: 2rem; max-width: 900px; margin: 0 auto; }
45
  #results_gallery .gallery-item { padding: 0.25rem !important; background-color: #374151; border: 1px solid #374151 !important; }
46
  #bottom_controls { max-width: 500px; margin: 2.5rem auto 1rem auto; }
47
- #bottom_controls .gr-accordion > .gr-block-label { text-align: center !important; display: block !important; }
48
  """
49
  with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="blue"), css=css, title="Pneumonia Detection AI") as demo:
50
 
@@ -68,22 +69,22 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="blue")
68
  with gr.Row():
69
  submit_analysis_btn = gr.Button("Analyze Images", variant="primary")
70
  cancel_btn = gr.Button("Cancel", variant="stop")
71
-
72
- # --- "About" Section (RESTORED) ---
73
  with gr.Column(elem_id="bottom_controls"):
74
  with gr.Accordion("About this Tool", open=False):
75
  gr.Markdown(
76
  """
77
- ### MLOps-Powered Pneumonia Detection
78
- This application demonstrates a complete, end-to-end MLOps pipeline for medical image classification. It leverages a state-of-the-art **Vision Transformer (ViT)** model, fine-tuned on a public dataset of chest X-ray images to distinguish between Normal and Pneumonia cases.
 
 
 
 
79
 
80
- **Disclaimer:** This tool is for demonstration and educational purposes only and is **not a substitute for professional medical advice.**
81
-
82
  ---
83
-
84
- **Project Team:**
85
- * **Alyyan Ahmed** - ML Engineer & Developer
86
- * **Munim Akbar** - ML Engineer & Developer
87
  """
88
  )
89
  with gr.Row():
@@ -95,37 +96,27 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="blue")
95
  with gr.Row():
96
  back_to_main_btn_hist = gr.Button("⬅️ Back to Main App")
97
  refresh_history_btn = gr.Button("Refresh History")
 
 
98
  history_df = gr.DataFrame(headers=["Name", "Age", "Prediction", "Confidence", "Date"], row_count=10, interactive=False)
99
 
100
  with gr.Column(visible=False) as samples_page:
101
  gr.Markdown("# 🖼️ Sample Image Library", elem_classes="app_title")
102
- gr.Markdown("Right-click on any image and select **'Save Image As...'** to download it for testing on the main page.")
103
  back_to_main_btn_samp = gr.Button("⬅️ Back to Main App")
104
-
105
  with gr.Row():
106
  with gr.Column():
107
  gr.Markdown("### Normal Cases")
108
- # Use a Gallery to display the images visually
109
- gr.Gallery(
110
- value=NORMAL_SAMPLES,
111
- label="Normal X-Rays",
112
- columns=5,
113
- object_fit="contain",
114
- height="auto"
115
- )
116
-
117
  with gr.Column():
118
  gr.Markdown("### Pneumonia Cases")
119
- # Use a Gallery for the pneumonia samples as well
120
- gr.Gallery(
121
- value=PNEUMONIA_SAMPLES,
122
- label="Pneumonia X-Rays",
123
- columns=5,
124
- object_fit="contain",
125
- height="auto"
126
- )
127
 
128
- # --- Event Handling Logic (Unchanged and Correct) ---
129
  def show_patient_info(files): return gr.update(visible=True) if files else gr.update(visible=False)
130
  image_input.upload(fn=show_patient_info, inputs=image_input, outputs=patient_info_modal)
131
  async def submit_and_hide_modal(name, age, files):
@@ -134,8 +125,10 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="blue")
134
  cancel_btn.click(lambda: (gr.update(visible=False), None), None, [patient_info_modal, image_input])
135
  start_over_btn.click(fn=None, js="() => { window.location.reload(); }")
136
 
 
137
  all_pages = [main_app, history_page, samples_page]
138
- async def show_history_page_and_refresh(): records_update = await refresh_history_table(); return [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), records_update]
 
139
  def show_samples_page(): return [gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)]
140
  def show_main_page(): return [gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)]
141
 
@@ -144,7 +137,17 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="blue")
144
  back_to_main_btn_hist.click(fn=show_main_page, outputs=all_pages)
145
  back_to_main_btn_samp.click(fn=show_main_page, outputs=all_pages)
146
 
 
147
  refresh_history_btn.click(fn=refresh_history_table, outputs=history_df)
 
 
 
 
 
 
 
 
 
148
  demo.load(fn=refresh_history_table, outputs=history_df)
149
 
150
  # --- Launch the App ---
 
1
+ # app.py (The Definitive Final Version)
2
+
3
  import gradio as gr
4
  from pathlib import Path
5
  import asyncio
6
 
7
  # Import backend components
8
  from app.prediction import PredictionPipeline
9
+ from app.database import add_patient_record, get_all_records, clear_all_records # Import the new function
10
 
11
  # --- Initialization ---
12
  prediction_pipeline = PredictionPipeline()
 
37
  # --- Gradio UI Definition ---
38
  css = """
39
  /* --- Professional Dark Theme & Fonts --- */
40
+ :root { --primary-hue: 220 !important; --secondary-hue: 210 !important; --neutral-hue: 210 !important; --body-background-fill: #111827 !important; --block-background-fill: #1F2337 !important; --block-border-width: 1px !important; --border-color-accent: #374151 !important; --background-fill-secondary: #1F2937 !important;}
41
+ /* --- Header & Title Styling (THE FIX) --- */
42
  #app_header { text-align: center; max-width: 900px; margin: 0 auto; }
43
+ #app_title { font-size: 3rem !important; font-weight: 800 !important; color: #FFFFFF !important; padding-top: 1rem; }
44
+ #app_subtitle { font-size: 1.25rem !important; color: #9CA3AF !important; margin-bottom: 2rem; }
45
  /* --- Layout and Spacing --- */
46
+ #main_container { gap: 2rem; max-width: 700px; margin: 0 auto; } /* Made it slightly narrower */
47
  #results_gallery .gallery-item { padding: 0.25rem !important; background-color: #374151; border: 1px solid #374151 !important; }
48
  #bottom_controls { max-width: 500px; margin: 2.5rem auto 1rem auto; }
 
49
  """
50
  with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="blue"), css=css, title="Pneumonia Detection AI") as demo:
51
 
 
69
  with gr.Row():
70
  submit_analysis_btn = gr.Button("Analyze Images", variant="primary")
71
  cancel_btn = gr.Button("Cancel", variant="stop")
 
 
72
  with gr.Column(elem_id="bottom_controls"):
73
  with gr.Accordion("About this Tool", open=False):
74
  gr.Markdown(
75
  """
76
+ ### 🩺 MLOps-Powered Pneumonia Detection
77
+
78
+ This project showcases a complete **end-to-end MLOps pipeline** for medical image classification.
79
+ It leverages a cutting-edge **Vision Transformer (ViT)** model, fine-tuned on publicly available chest X-ray datasets, to classify images into **Normal** or **Pneumonia** cases.
80
+
81
+ ⚠️ **Disclaimer:** This application is intended **solely for educational and demonstration purposes**. It is **not a medical diagnostic tool** and must not be used as a substitute for professional medical advice.
82
 
 
 
83
  ---
84
+
85
+ ### 👥 Project Team
86
+ - **Alyyan Ahmed** ML Engineer & Developer
87
+ - **Munim Akbar** ML Engineer & Developer
88
  """
89
  )
90
  with gr.Row():
 
96
  with gr.Row():
97
  back_to_main_btn_hist = gr.Button("⬅️ Back to Main App")
98
  refresh_history_btn = gr.Button("Refresh History")
99
+ # --- NEW: Clear History Button ---
100
+ clear_history_btn = gr.Button("⚠️ Clear All History", variant="stop")
101
  history_df = gr.DataFrame(headers=["Name", "Age", "Prediction", "Confidence", "Date"], row_count=10, interactive=False)
102
 
103
  with gr.Column(visible=False) as samples_page:
104
  gr.Markdown("# 🖼️ Sample Image Library", elem_classes="app_title")
105
+ gr.Markdown("You can download these sample images to test the tool on the main page.")
106
  back_to_main_btn_samp = gr.Button("⬅️ Back to Main App")
 
107
  with gr.Row():
108
  with gr.Column():
109
  gr.Markdown("### Normal Cases")
110
+ for img_path in NORMAL_SAMPLES:
111
+ gr.File(value=img_path, label=Path(img_path).name, interactive=False)
 
 
 
 
 
 
 
112
  with gr.Column():
113
  gr.Markdown("### Pneumonia Cases")
114
+ for img_path in PNEUMONIA_SAMPLES:
115
+ gr.File(value=img_path, label=Path(img_path).name, interactive=False)
116
+
117
+ # --- Event Handling Logic ---
 
 
 
 
118
 
119
+ # ... (main page handlers are correct)
120
  def show_patient_info(files): return gr.update(visible=True) if files else gr.update(visible=False)
121
  image_input.upload(fn=show_patient_info, inputs=image_input, outputs=patient_info_modal)
122
  async def submit_and_hide_modal(name, age, files):
 
125
  cancel_btn.click(lambda: (gr.update(visible=False), None), None, [patient_info_modal, image_input])
126
  start_over_btn.click(fn=None, js="() => { window.location.reload(); }")
127
 
128
+ # --- Page Navigation (correct) ---
129
  all_pages = [main_app, history_page, samples_page]
130
+ async def show_history_page_and_refresh():
131
+ records_update = await refresh_history_table(); return [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), records_update]
132
  def show_samples_page(): return [gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)]
133
  def show_main_page(): return [gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)]
134
 
 
137
  back_to_main_btn_hist.click(fn=show_main_page, outputs=all_pages)
138
  back_to_main_btn_samp.click(fn=show_main_page, outputs=all_pages)
139
 
140
+ # --- History Page Logic ---
141
  refresh_history_btn.click(fn=refresh_history_table, outputs=history_df)
142
+
143
+ # --- NEW: Clear History Logic ---
144
+ async def clear_history_and_refresh():
145
+ deleted_count = await clear_all_records()
146
+ gr.Info(f"Successfully deleted {deleted_count} records.")
147
+ # After deleting, immediately refresh the table to show it's empty
148
+ return await refresh_history_table()
149
+ clear_history_btn.click(fn=clear_history_and_refresh, outputs=history_df)
150
+
151
  demo.load(fn=refresh_history_table, outputs=history_df)
152
 
153
  # --- Launch the App ---