rajkhanke commited on
Commit
c96f14a
Β·
verified Β·
1 Parent(s): 7bc57bd

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +232 -0
app.py ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from google import genai
3
+ from PIL import Image
4
+ import os
5
+ from typing import Tuple, Optional
6
+ import logging
7
+
8
+ # Configure logging
9
+ logging.basicConfig(level=logging.INFO)
10
+ logger = logging.getLogger(_name_)
11
+
12
+ class CTScanAnalyzer:
13
+ def _init_(self, api_key: str):
14
+ """Initialize the CT Scan Analyzer with API key and configuration."""
15
+ self.client = genai.Client(api_key=api_key)
16
+ self.setup_page_config()
17
+ self.apply_custom_styles()
18
+
19
+ @staticmethod
20
+ def setup_page_config() -> None:
21
+ """Configure Streamlit page settings."""
22
+ st.set_page_config(
23
+ page_title="CT Scan Analytics",
24
+ page_icon="πŸ₯",
25
+ layout="wide"
26
+ )
27
+
28
+ @staticmethod
29
+ def apply_custom_styles() -> None:
30
+ """Apply custom CSS styles with improved dark theme."""
31
+ st.markdown("""
32
+ <style>
33
+ :root {
34
+ --background-color: #1a1a1a;
35
+ --secondary-bg: #2d2d2d;
36
+ --text-color: #e0e0e0;
37
+ --accent-color: #4CAF50;
38
+ --border-color: #404040;
39
+ --hover-color: #45a049;
40
+ }
41
+
42
+ .main { background-color: var(--background-color); }
43
+ .stApp { background-color: var(--background-color); }
44
+
45
+ .stButton>button {
46
+ width: 100%;
47
+ background-color: var(--accent-color);
48
+ color: white;
49
+ padding: 0.75rem;
50
+ border-radius: 6px;
51
+ border: none;
52
+ font-weight: 600;
53
+ transition: background-color 0.3s ease;
54
+ }
55
+ .stButton>button:hover {
56
+ background-color: var(--hover-color);
57
+ }
58
+
59
+ .report-container {
60
+ background-color: var(--secondary-bg);
61
+ padding: 2rem;
62
+ border-radius: 12px;
63
+ margin: 1rem 0;
64
+ border: 1px solid var(--border-color);
65
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
66
+ }
67
+ </style>
68
+ """, unsafe_allow_html=True)
69
+
70
+ def analyze_image(self, img: Image.Image) -> Tuple[Optional[str], Optional[str]]:
71
+ """
72
+ Analyze CT scan image using Gemini AI.
73
+ Returns tuple of (doctor_analysis, patient_analysis).
74
+ """
75
+ try:
76
+ prompts = {
77
+ "doctor": """
78
+ Provide a structured analysis of this CT scan for medical professionals without including any introductory or acknowledgment phrases.
79
+ Follow the structure below:
80
+
81
+ 1. Initial Observations
82
+ - Key anatomical structures
83
+ - Tissue density patterns
84
+ - Contrast enhancement patterns
85
+
86
+ 2. Detailed Findings
87
+ - Primary abnormalities
88
+ - Secondary findings
89
+ - Measurements and dimensions
90
+
91
+ 3. Clinical Correlation
92
+ - Differential diagnoses
93
+ - Recommended additional imaging
94
+ - Suggested clinical correlation
95
+
96
+ 4. Technical Assessment
97
+ - Image quality
98
+ - Positioning
99
+ - Artifacts if present
100
+ """,
101
+
102
+ "patient": """
103
+ Explain this CT scan in clear, simple terms for a patient without including any introductory or acknowledgment phrases.
104
+ Follow the structure below:
105
+
106
+ 1. What We're Looking At
107
+ - The part of the body shown
108
+ - What appears normal
109
+ - Any notable findings
110
+
111
+ 2. Next Steps
112
+ - What these findings might mean
113
+ - Questions to ask your doctor
114
+ - Any follow-up that might be needed
115
+
116
+ Remember to use everyday language and avoid medical terminology.
117
+ """
118
+ }
119
+
120
+ responses = {}
121
+ for audience, prompt in prompts.items():
122
+ response = self.client.models.generate_content(
123
+ model="gemini-2.0-flash",
124
+ contents=[prompt, img]
125
+ )
126
+ responses[audience] = response.text if hasattr(response, 'text') else None
127
+
128
+ return responses["doctor"], responses["patient"]
129
+
130
+ except Exception as e:
131
+ logger.error(f"Analysis failed: {str(e)}")
132
+ return None, None
133
+
134
+ def run(self):
135
+ """Run the Streamlit application."""
136
+ st.title("πŸ₯ CT Scan Analytics")
137
+ st.markdown("""
138
+ Advanced CT scan analysis powered by AI. Upload your scan for instant
139
+ insights tailored for both medical professionals and patients.
140
+ """)
141
+
142
+ col1, col2 = st.columns([1, 1.5])
143
+
144
+ with col1:
145
+ uploaded_file = self.handle_file_upload()
146
+
147
+ with col2:
148
+ if uploaded_file:
149
+ self.process_analysis(uploaded_file)
150
+ else:
151
+ self.show_instructions()
152
+
153
+ self.show_footer()
154
+
155
+ def handle_file_upload(self) -> Optional[object]:
156
+ """Handle file upload and display image preview."""
157
+ uploaded_file = st.file_uploader(
158
+ "Upload CT Scan Image",
159
+ type=["png", "jpg", "jpeg"],
160
+ help="Supported formats: PNG, JPG, JPEG"
161
+ )
162
+
163
+ if uploaded_file:
164
+ img = Image.open(uploaded_file)
165
+ st.image(img, caption="Uploaded CT Scan", use_column_width=True)
166
+
167
+ with st.expander("Image Details"):
168
+ st.write(f"*Filename:* {uploaded_file.name}")
169
+ st.write(f"*Size:* {uploaded_file.size/1024:.2f} KB")
170
+ st.write(f"*Format:* {img.format}")
171
+ st.write(f"*Dimensions:* {img.size[0]}x{img.size[1]} pixels")
172
+
173
+ return uploaded_file
174
+
175
+ def process_analysis(self, uploaded_file: object) -> None:
176
+ """Process the uploaded image and display analysis."""
177
+ if st.button("πŸ” Analyze CT Scan", key="analyze_button"):
178
+ with st.spinner("Analyzing CT scan..."):
179
+ img = Image.open(uploaded_file)
180
+ doctor_analysis, patient_analysis = self.analyze_image(img)
181
+
182
+ if doctor_analysis and patient_analysis:
183
+ tab1, tab2 = st.tabs(["πŸ“‹ Medical Report", "πŸ‘₯ Patient Summary"])
184
+
185
+ with tab1:
186
+ st.markdown("### Medical Professional's Report")
187
+ st.markdown(f"<div class='report-container'>{doctor_analysis}</div>",
188
+ unsafe_allow_html=True)
189
+
190
+ with tab2:
191
+ st.markdown("### Patient-Friendly Explanation")
192
+ st.markdown(f"<div class='report-container'>{patient_analysis}</div>",
193
+ unsafe_allow_html=True)
194
+ else:
195
+ st.error("Analysis failed. Please try again.")
196
+
197
+ @staticmethod
198
+ def show_instructions() -> None:
199
+ """Display instructions when no image is uploaded."""
200
+ st.info("πŸ‘ˆ Upload a CT scan image to begin analysis")
201
+
202
+ with st.expander("β„Ή How it works"):
203
+ st.markdown("""
204
+ 1. *Upload* your CT scan image
205
+ 2. Click *Analyze*
206
+ 3. Receive two detailed reports:
207
+ - Technical analysis for medical professionals
208
+ - Patient-friendly explanation
209
+ """)
210
+
211
+ @staticmethod
212
+ def show_footer() -> None:
213
+ st.markdown("---")
214
+ st.markdown(
215
+ """
216
+ <div style='text-align: center'>
217
+ <p style='color: #888888; font-size: 0.8em;'>
218
+ UNDER DEVELOPMENT
219
+ </p>
220
+ </div>
221
+ """,
222
+ unsafe_allow_html=True
223
+ )
224
+
225
+ if _name_ == "_main_":
226
+ # Get API key from environment variable
227
+ api_key = "AIzaSyCp9j5OGZb5hlykMIAJhbDII3IHYJWCrnQ"
228
+ if not api_key:
229
+ st.error("Please set GEMINI_API_KEY environment variable")
230
+ else:
231
+ analyzer = CTScanAnalyzer(api_key)
232
+ analyzer.run()