pinge commited on
Commit
0eaad25
·
1 Parent(s): c393d43

Deploy Streamlit app

Browse files
Files changed (2) hide show
  1. app.py +294 -0
  2. requirements.txt +9 -0
app.py ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from groq import Groq
3
+ import base64
4
+ from PIL import Image
5
+ import io
6
+ import os
7
+ from dotenv import load_dotenv
8
+ from io import BytesIO
9
+ import requests
10
+ import streamlit.components.v1 as components
11
+
12
+ st.set_page_config(page_title="My App", page_icon="", layout="wide", initial_sidebar_state="collapsed")
13
+ import streamlit as st
14
+
15
+ # Initialize session state for dark mode (default: True)
16
+ if "dark_mode" not in st.session_state:
17
+ st.session_state.dark_mode = True
18
+
19
+ # Icon switch
20
+ icon = "☀️" if st.session_state.dark_mode else "🌙"
21
+
22
+ # Toggle button (tap to switch modes)
23
+ if st.button(icon, key="dark_mode_toggle"):
24
+ st.session_state.dark_mode = not st.session_state.dark_mode
25
+ st.rerun()
26
+
27
+ # Apply styles for dark & light modes
28
+ if st.session_state.dark_mode:
29
+ st.markdown(
30
+ """
31
+ <style>
32
+ body, .stApp { background-color: #121212; color: white; }
33
+ h1, h2, h3, p, label { color: white !important; }
34
+ .stTextInput, .stButton > button, .stSelectbox, .stTextArea {
35
+ background-color: #222;
36
+ color: white;
37
+ border-radius: 10px;
38
+ border: 1px solid #444;
39
+ }
40
+ .stMarkdown a { color: #4db8ff; }
41
+ .stAlert { background-color: #222; color: white; }
42
+ </style>
43
+ """,
44
+ unsafe_allow_html=True,
45
+ )
46
+ else:
47
+ st.markdown(
48
+ """
49
+ <style>
50
+ body, .stApp { background-color: #ffffff; color: #333; }
51
+ h1, h2, h3, p, label { color: #333 !important; }
52
+ .stTextInput, .stButton > button, .stSelectbox, .stTextArea {
53
+ background-color: #f8f9fa;
54
+ color: #333;
55
+ border-radius: 10px;
56
+ border: 1px solid #ccc;
57
+ }
58
+ .stMarkdown a { color: #007bff; }
59
+ .stAlert { background-color: #f8f9fa; color: #333; }
60
+ </style>
61
+ """,
62
+ unsafe_allow_html=True,
63
+ )
64
+
65
+
66
+ # Hides Streamlit UI elements with CSS
67
+ hide_streamlit_style = """
68
+ <style>
69
+ #MainMenu {visibility: hidden;}
70
+ footer {visibility: hidden;}
71
+ header {visibility: hidden;}
72
+ .stDeployButton {display: none !important;}
73
+ [data-testid="stProfileMenu"] {display: none !important;}
74
+ </style>
75
+ """
76
+ st.markdown(hide_streamlit_style, unsafe_allow_html=True)
77
+
78
+
79
+
80
+
81
+ # Load environment variables from .env file
82
+ load_dotenv()
83
+
84
+ # Retrieve Groq API key from environment variables
85
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
86
+
87
+ # Check if API key is loaded correctly
88
+ if not GROQ_API_KEY:
89
+ st.error("Groq API key not found. Please set it in the .env file.")
90
+ st.stop()
91
+
92
+ # Initialize Groq client
93
+ client = Groq(api_key=GROQ_API_KEY)
94
+
95
+ def encode_image(image):
96
+ """Convert a PIL Image object to base64-encoded JPEG format"""
97
+ # Convert RGBA to RGB if needed
98
+ if image.mode == "RGBA":
99
+ image = image.convert("RGB")
100
+
101
+ # Save image as JPEG in memory
102
+ buffer = BytesIO()
103
+ image.save(buffer, format="JPEG")
104
+ base64_image = base64.b64encode(buffer.getvalue()).decode("utf-8")
105
+
106
+ return base64_image
107
+
108
+ # Function to classify MRI image using Groq API
109
+ def classify_mri_image(image):
110
+ base64_image = encode_image(image)
111
+
112
+ # Prompt for the Groq API
113
+ prompt = "Analyze this MRI image and determine if it shows a brain tumor. Provide a clear classification (e.g., 'Tumor detected' or 'No tumor detected') and a brief explanation."
114
+
115
+ # Call Groq API with Llama 3.2-90B Vision Preview
116
+ response = client.chat.completions.create(
117
+ model="llama-3.2-90b-vision-preview",
118
+ messages=[
119
+ {
120
+ "role": "user",
121
+ "content": [
122
+ {"type": "text", "text": prompt},
123
+ {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}}
124
+ ]
125
+ }
126
+ ],
127
+ max_tokens=300
128
+ )
129
+
130
+ # Extract the response
131
+ result = response.choices[0].message.content
132
+ return result
133
+
134
+ # Streamlit app
135
+ def main():
136
+ st.title("MRI Brain Tumor Classifier")
137
+ st.write("Upload an MRI image to classify whether it contains a brain tumor.")
138
+
139
+ uploaded_file = st.file_uploader("Choose an MRI image...", type=["jpg", "jpeg", "png"])
140
+
141
+ if uploaded_file is not None:
142
+ image = Image.open(uploaded_file)
143
+ st.image(image, caption="Uploaded MRI Image", use_container_width=True)
144
+
145
+ if st.button("Classify Image"):
146
+ with st.spinner("Classifying..."):
147
+ try:
148
+ result = classify_mri_image(image)
149
+ st.success("Classification Complete!")
150
+ st.write("### Result:")
151
+ st.write(result)
152
+ except Exception as e:
153
+ st.error(f"An error occurred: {str(e)}")
154
+
155
+ if __name__ == "__main__":
156
+ main()
157
+
158
+
159
+
160
+ st.markdown("---")
161
+
162
+
163
+ # Function to check if the question is related to brain tumors
164
+ def is_brain_tumor_question(user_input):
165
+ keywords = [
166
+ "brain tumor", "glioma", "meningioma", "astrocytoma", "medulloblastoma",
167
+ "ependymoma", "oligodendroglioma", "pituitary tumor", "schwannoma", "craniopharyngioma",
168
+ "cancer", "brain cancer", "malignant tumor", "benign tumor",
169
+ "neurology", "oncology", "neurosurgeon", "brain MRI", "CT scan brain", "tumor diagnosis",
170
+ "tumor treatment", "chemotherapy", "radiotherapy", "stereotactic radiosurgery",
171
+ "brain surgery", "craniotomy", "tumor removal", "brain biopsy",
172
+ "symptoms of brain tumor", "headache and tumor", "seizures and tumor",
173
+ "brain tumor prognosis", "life expectancy brain tumor", "brain metastases",
174
+ "tumor recurrence", "brain swelling", "intracranial pressure", "glioblastoma multiforme",
175
+ "brain tumor in children", "brain tumor in adults", "radiation therapy for brain tumors", "brain",
176
+ "brain-tumor"
177
+ ]
178
+ return any(keyword in user_input.lower() for keyword in keywords)
179
+
180
+ # Function to interact with Groq chatbot
181
+ def get_chatbot_response(user_input):
182
+ if not is_brain_tumor_question(user_input):
183
+ return "I can only answer brain tumor-related questions."
184
+
185
+ url = "https://api.groq.com/openai/v1/chat/completions"
186
+ headers = {
187
+ "Authorization": f"Bearer {GROQ_API_KEY}",
188
+ "Content-Type": "application/json"
189
+ }
190
+ payload = {
191
+ "model": "llama3-8b-8192",
192
+ "messages": [
193
+ {"role": "system", "content": "You are a helpful AI that answers only brain tumor-related questions. Keep responses a little bit brief if question doesn't demand explanations."},
194
+ {"role": "user", "content": user_input}
195
+ ]
196
+ }
197
+
198
+ try:
199
+ response = requests.post(url, headers=headers, json=payload)
200
+ response_data = response.json()
201
+ if response.status_code == 200:
202
+ return response_data.get("choices", [{}])[0].get("message", {}).get("content", "No response generated.")
203
+ else:
204
+ return f"Error {response.status_code}: {response_data.get('error', {}).get('message', 'Unknown error')}"
205
+ except requests.exceptions.RequestException as e:
206
+ return f"Request failed: {e}"
207
+
208
+ # Custom CSS for styling the input and send icon
209
+ import streamlit as st
210
+
211
+ st.markdown("""
212
+ <style>
213
+ .chat-container {
214
+ display: flex;
215
+ flex-direction: column;
216
+ align-items: center;
217
+ border: 1px solid #444;
218
+ border-radius: 20px;
219
+ padding: 10px;
220
+ background-color: #222;
221
+ width: 100%;
222
+ max-width: 400px;
223
+ margin: auto;
224
+ }
225
+ .chat-input {
226
+ height: 45px;
227
+ font-size: 17px; /* Slightly increased */
228
+ border: none;
229
+ width: 100%;
230
+ max-width: 400px;
231
+ border-radius: 10px;
232
+ padding: 10px;
233
+ background-color: #333;
234
+ color: white;
235
+ outline: none;
236
+ }
237
+ .send-button {
238
+ cursor: pointer;
239
+ font-weight: bold;
240
+ text-align: center;
241
+ background-color: #111f3f;
242
+ color: white;
243
+ transition: background 0.3s ease-in-out;
244
+ margin-top: 10px;
245
+ border: none;
246
+ border-radius: 10px;
247
+ width: 100%;
248
+ max-width: 400px;
249
+ height: 45px;
250
+ padding: 12px;
251
+ font-size: 17px; /* Slightly increased */
252
+ }
253
+ .send-button:hover {
254
+ background-color: #888888; /* Slightly darker gray on hover */
255
+ }
256
+
257
+ /* Mobile View */
258
+ @media (max-width: 600px) {
259
+ .chat-container {
260
+ width: 90%;
261
+ }
262
+ .chat-input {
263
+ width: 100%;
264
+ font-size: 16px; /* Slightly increased */
265
+ height: 40px;
266
+ padding: 8px;
267
+ }
268
+ .send-button {
269
+ width: 128px; /* 2 inches */
270
+ font-size: 16px; /* Slightly increased */
271
+ height: 40px;
272
+ padding: 8px;
273
+ }
274
+ }
275
+ </style>
276
+
277
+ """, unsafe_allow_html=True)
278
+
279
+ st.write("Ask me any brain tumor-related questions")
280
+
281
+ user_input = st.text_input("", placeholder="Enter your question...", key="input_box", label_visibility="collapsed")
282
+
283
+ st.markdown("""
284
+ <div style="display: flex; justify-content: center; width: 100%; margin-top: 10px;">
285
+ <button class="send-button" onclick="sendMessage()">Send</button>
286
+ </div>
287
+ """, unsafe_allow_html=True)
288
+
289
+ if user_input:
290
+ st.write("") # Adds a space before generating the response
291
+ with st.spinner("Thinking..."):
292
+ response = get_chatbot_response(user_input)
293
+ st.write(response)
294
+
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ tensorflow-cpu
3
+ numpy
4
+ matplotlib
5
+ Pillow
6
+ opencv-python-headless
7
+ requests
8
+ python-dotenv
9
+ groq