LuckyHappyFish commited on
Commit
2759f88
·
1 Parent(s): b1f272d

initial commit

Browse files
Files changed (1) hide show
  1. app.py +190 -67
app.py CHANGED
@@ -13,11 +13,21 @@ st.set_page_config(
13
  initial_sidebar_state="expanded",
14
  )
15
 
 
 
 
 
 
 
 
 
 
16
  # Custom CSS to improve styling and responsiveness
17
- def local_css():
18
- st.markdown(
19
- """
20
  <style>
 
21
  /* Main layout */
22
  .main {
23
  background-color: #f0f2f6;
@@ -26,7 +36,7 @@ def local_css():
26
  .title h1 {
27
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
28
  text-align: center;
29
- color: #ff4b4b;
30
  font-size: 3rem;
31
  margin-bottom: 20px;
32
  }
@@ -38,32 +48,32 @@ def local_css():
38
  }
39
  /* Sidebar styling */
40
  [data-testid="stSidebar"] {
41
- background-color: #ff4b4b;
42
  }
43
  [data-testid="stSidebar"] .css-ng1t4o {
44
- color: white;
45
  }
46
  [data-testid="stSidebar"] .css-1d391kg {
47
- color: white;
48
  }
49
  /* File uploader styling */
50
  .stFileUploader {
51
- border: 2px dashed #ff4b4b;
52
  border-radius: 10px;
53
  padding: 20px;
54
  text-align: center;
55
- color: #ff4b4b;
56
- background-color: #ffffff;
57
  font-weight: bold;
58
  }
59
  /* File uploader hover effect */
60
  .stFileUploader:hover {
61
- background-color: #ffe5e5;
62
  }
63
  /* Button styling */
64
  .stButton>button {
65
- background-color: #ff4b4b;
66
- color: white;
67
  border: none;
68
  padding: 0.7rem 1.5rem;
69
  border-radius: 5px;
@@ -72,22 +82,23 @@ def local_css():
72
  margin-top: 10px;
73
  }
74
  .stButton>button:hover {
75
- background-color: #e04343;
76
- color: white;
77
  }
78
  /* Headers styling */
79
  h2 {
80
- color: #ff4b4b;
81
  margin-top: 30px;
82
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
83
  }
84
  h3 {
85
- color: #ff4b4b;
86
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
87
  }
88
  /* Text styling */
89
  .stMarkdown p {
90
  font-size: 1.1rem;
 
91
  }
92
  /* Footer styling */
93
  footer {
@@ -125,20 +136,129 @@ def local_css():
125
  border: 2px solid transparent;
126
  }
127
  .sample-images img:hover {
128
- border: 2px solid #ff4b4b;
129
  }
130
  </style>
131
- """,
132
- unsafe_allow_html=True
133
- )
134
-
135
- local_css()
136
-
137
- # Hugging Face API key
138
- API_KEY = st.secrets["HF_API_KEY"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
- # Initialize the Hugging Face Inference Client
141
- client = InferenceClient(api_key=API_KEY)
142
 
143
  # Load the image classification pipeline
144
  @st.cache_resource
@@ -156,6 +276,8 @@ def get_ingredients_qwen(food_name):
156
  Generate a list of ingredients for the given food item using Qwen NLP model.
157
  Returns a clean, comma-separated list of ingredients.
158
  """
 
 
159
  messages = [
160
  {
161
  "role": "user",
@@ -164,7 +286,7 @@ def get_ingredients_qwen(food_name):
164
  }
165
  ]
166
  try:
167
- completion = client.chat.completions.create(
168
  model="Qwen/Qwen2.5-Coder-32B-Instruct",
169
  messages=messages,
170
  max_tokens=50
@@ -200,53 +322,54 @@ sample_images = {
200
  }
201
 
202
  cols = st.columns(len(sample_images))
 
203
  for idx, (name, file_path) in enumerate(sample_images.items()):
204
  with cols[idx]:
205
  if st.button(f"{name}", key=name):
206
- uploaded_file = file_path
207
 
208
  # File uploader
209
  st.subheader("Upload a food image:")
210
  uploaded_file = st.file_uploader("", type=["jpg", "png", "jpeg"])
211
 
212
- if 'uploaded_file' in locals() and uploaded_file is not None:
213
- # Display the uploaded image
214
- if isinstance(uploaded_file, str):
215
- # Sample image selected
216
- image = Image.open(uploaded_file)
217
- else:
218
- # User uploaded image
219
- image = Image.open(uploaded_file)
220
  st.image(image, caption="Uploaded Image", use_container_width=True)
221
-
222
- # Classification button
223
- if st.button("Classify"):
224
- with st.spinner("Classifying..."):
225
- # Make predictions
226
- predictions = pipe_classification(image)
227
-
228
- # Display only the top prediction
229
- top_food = predictions[0]['label']
230
- st.header(f"🍽️ Food: {top_food}")
231
-
232
- # Generate and display ingredients for the top prediction
233
- st.subheader("📝 Ingredients")
234
- try:
235
- ingredients = get_ingredients_qwen(top_food)
236
- st.write(ingredients)
237
- except Exception as e:
238
- st.error(f"Error generating ingredients: {e}")
239
-
240
- st.subheader("💡 Healthier Alternatives")
241
- try:
242
- client_gradio = Client("https://8a56cb969da1f9d721.gradio.live/")
243
- result = client_gradio.predict(
244
- query=f"What's a healthy {top_food} recipe, and why is it healthy?",
245
- api_name="/get_response"
246
- )
247
- st.write(result)
248
- except Exception as e:
249
- st.error(f"Unable to contact RAG: {e}")
250
  else:
251
  st.info("Please select or upload an image to get started.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
 
 
 
 
 
 
 
 
 
 
 
13
  initial_sidebar_state="expanded",
14
  )
15
 
16
+ # Initialize mode in session state
17
+ if 'mode' not in st.session_state:
18
+ st.session_state['mode'] = 'Light Mode'
19
+
20
+ # Light/Dark mode toggle
21
+ mode = st.sidebar.selectbox('Select Mode', options=['Light Mode', 'Dark Mode'], index=0 if st.session_state['mode'] == 'Light Mode' else 1)
22
+
23
+ st.session_state['mode'] = mode
24
+
25
  # Custom CSS to improve styling and responsiveness
26
+ def local_css(mode='Light Mode'):
27
+ if mode == 'Light Mode':
28
+ css_string = '''
29
  <style>
30
+ /* Light mode CSS */
31
  /* Main layout */
32
  .main {
33
  background-color: #f0f2f6;
 
36
  .title h1 {
37
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
38
  text-align: center;
39
+ color: #000000; /* Black color */
40
  font-size: 3rem;
41
  margin-bottom: 20px;
42
  }
 
48
  }
49
  /* Sidebar styling */
50
  [data-testid="stSidebar"] {
51
+ background-color: #ffffff; /* White color */
52
  }
53
  [data-testid="stSidebar"] .css-ng1t4o {
54
+ color: #000000; /* Black color */
55
  }
56
  [data-testid="stSidebar"] .css-1d391kg {
57
+ color: #000000; /* Black color */
58
  }
59
  /* File uploader styling */
60
  .stFileUploader {
61
+ border: 2px dashed #000000; /* Black color */
62
  border-radius: 10px;
63
  padding: 20px;
64
  text-align: center;
65
+ color: #000000; /* Black color */
66
+ background-color: #ffffff; /* White background */
67
  font-weight: bold;
68
  }
69
  /* File uploader hover effect */
70
  .stFileUploader:hover {
71
+ background-color: #e0e0e0;
72
  }
73
  /* Button styling */
74
  .stButton>button {
75
+ background-color: #000000; /* Black background */
76
+ color: #ffffff; /* White text */
77
  border: none;
78
  padding: 0.7rem 1.5rem;
79
  border-radius: 5px;
 
82
  margin-top: 10px;
83
  }
84
  .stButton>button:hover {
85
+ background-color: #333333; /* Darker black */
86
+ color: #ffffff;
87
  }
88
  /* Headers styling */
89
  h2 {
90
+ color: #000000; /* Black color */
91
  margin-top: 30px;
92
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
93
  }
94
  h3 {
95
+ color: #000000; /* Black color */
96
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
97
  }
98
  /* Text styling */
99
  .stMarkdown p {
100
  font-size: 1.1rem;
101
+ color: #000000;
102
  }
103
  /* Footer styling */
104
  footer {
 
136
  border: 2px solid transparent;
137
  }
138
  .sample-images img:hover {
139
+ border: 2px solid #000000; /* Black border on hover */
140
  }
141
  </style>
142
+ '''
143
+ else:
144
+ css_string = '''
145
+ <style>
146
+ /* Dark mode CSS */
147
+ /* Main layout */
148
+ .main {
149
+ background-color: #1e1e1e;
150
+ }
151
+ /* Title styling */
152
+ .title h1 {
153
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
154
+ text-align: center;
155
+ color: #ffffff; /* White color */
156
+ font-size: 3rem;
157
+ margin-bottom: 20px;
158
+ }
159
+ /* Image styling */
160
+ .st-image img {
161
+ border-radius: 15px;
162
+ margin-bottom: 20px;
163
+ max-width: 100%;
164
+ }
165
+ /* Sidebar styling */
166
+ [data-testid="stSidebar"] {
167
+ background-color: #333333; /* Dark gray */
168
+ }
169
+ [data-testid="stSidebar"] .css-ng1t4o {
170
+ color: #ffffff; /* White color */
171
+ }
172
+ [data-testid="stSidebar"] .css-1d391kg {
173
+ color: #ffffff; /* White color */
174
+ }
175
+ /* File uploader styling */
176
+ .stFileUploader {
177
+ border: 2px dashed #ffffff; /* White color */
178
+ border-radius: 10px;
179
+ padding: 20px;
180
+ text-align: center;
181
+ color: #ffffff; /* White color */
182
+ background-color: #1e1e1e; /* Dark background */
183
+ font-weight: bold;
184
+ }
185
+ /* File uploader hover effect */
186
+ .stFileUploader:hover {
187
+ background-color: #333333;
188
+ }
189
+ /* Button styling */
190
+ .stButton>button {
191
+ background-color: #ffffff; /* White background */
192
+ color: #000000; /* Black text */
193
+ border: none;
194
+ padding: 0.7rem 1.5rem;
195
+ border-radius: 5px;
196
+ font-size: 1.1rem;
197
+ font-weight: bold;
198
+ margin-top: 10px;
199
+ }
200
+ .stButton>button:hover {
201
+ background-color: #e0e0e0; /* Lighter gray */
202
+ color: #000000;
203
+ }
204
+ /* Headers styling */
205
+ h2 {
206
+ color: #ffffff; /* White color */
207
+ margin-top: 30px;
208
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
209
+ }
210
+ h3 {
211
+ color: #ffffff; /* White color */
212
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
213
+ }
214
+ /* Text styling */
215
+ .stMarkdown p {
216
+ font-size: 1.1rem;
217
+ color: #ffffff; /* White text */
218
+ }
219
+ /* Footer styling */
220
+ footer {
221
+ visibility: hidden;
222
+ }
223
+ /* Hide sidebar on small screens */
224
+ @media only screen and (max-width: 600px) {
225
+ [data-testid="stSidebar"] {
226
+ display: none;
227
+ }
228
+ .main .block-container {
229
+ padding-left: 1rem;
230
+ padding-right: 1rem;
231
+ }
232
+ .title h1 {
233
+ font-size: 2rem;
234
+ }
235
+ .stButton>button {
236
+ width: 100%;
237
+ }
238
+ }
239
+ /* Sample images grid */
240
+ .sample-images {
241
+ display: flex;
242
+ justify-content: center;
243
+ flex-wrap: wrap;
244
+ gap: 10px;
245
+ }
246
+ .sample-images img {
247
+ width: 150px;
248
+ height: 150px;
249
+ object-fit: cover;
250
+ border-radius: 10px;
251
+ cursor: pointer;
252
+ border: 2px solid transparent;
253
+ }
254
+ .sample-images img:hover {
255
+ border: 2px solid #ffffff; /* White border on hover */
256
+ }
257
+ </style>
258
+ '''
259
+ st.markdown(css_string, unsafe_allow_html=True)
260
 
261
+ local_css(st.session_state['mode'])
 
262
 
263
  # Load the image classification pipeline
264
  @st.cache_resource
 
276
  Generate a list of ingredients for the given food item using Qwen NLP model.
277
  Returns a clean, comma-separated list of ingredients.
278
  """
279
+ API_KEY = st.secrets["HF_API_KEY"]
280
+ client = InferenceClient(api_key=API_KEY)
281
  messages = [
282
  {
283
  "role": "user",
 
286
  }
287
  ]
288
  try:
289
+ completion = client.chat_completions.create(
290
  model="Qwen/Qwen2.5-Coder-32B-Instruct",
291
  messages=messages,
292
  max_tokens=50
 
322
  }
323
 
324
  cols = st.columns(len(sample_images))
325
+ selected_sample = None
326
  for idx, (name, file_path) in enumerate(sample_images.items()):
327
  with cols[idx]:
328
  if st.button(f"{name}", key=name):
329
+ selected_sample = file_path
330
 
331
  # File uploader
332
  st.subheader("Upload a food image:")
333
  uploaded_file = st.file_uploader("", type=["jpg", "png", "jpeg"])
334
 
335
+ if selected_sample:
336
+ # Sample image selected
337
+ image = Image.open(selected_sample)
338
+ st.image(image, caption="Selected Sample Image", use_container_width=True)
339
+ classify = st.button("Classify", key="classify_sample")
340
+ elif uploaded_file is not None:
341
+ # User uploaded image
342
+ image = Image.open(uploaded_file)
343
  st.image(image, caption="Uploaded Image", use_container_width=True)
344
+ classify = st.button("Classify", key="classify_upload")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  else:
346
  st.info("Please select or upload an image to get started.")
347
+ classify = False
348
+
349
+ if classify:
350
+ with st.spinner("Classifying..."):
351
+ # Make predictions
352
+ predictions = pipe_classification(image)
353
+
354
+ # Display only the top prediction
355
+ top_food = predictions[0]['label']
356
+ st.header(f"🍽️ Food: {top_food}")
357
+
358
+ # Generate and display ingredients for the top prediction
359
+ st.subheader("📝 Ingredients")
360
+ try:
361
+ ingredients = get_ingredients_qwen(top_food)
362
+ st.write(ingredients)
363
+ except Exception as e:
364
+ st.error(f"Error generating ingredients: {e}")
365
 
366
+ st.subheader("💡 Healthier Alternatives")
367
+ try:
368
+ client_gradio = Client("https://8a56cb969da1f9d721.gradio.live/")
369
+ result = client_gradio.predict(
370
+ query=f"What's a healthy {top_food} recipe, and why is it healthy?",
371
+ api_name="/get_response"
372
+ )
373
+ st.write(result)
374
+ except Exception as e:
375
+ st.error(f"Unable to contact RAG: {e}")