LuckyHappyFish commited on
Commit
07326b1
·
1 Parent(s): b6dc022

initial commit

Browse files
Files changed (1) hide show
  1. app.py +91 -194
app.py CHANGED
@@ -13,206 +13,100 @@ st.set_page_config(
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'],
22
- index=0 if st.session_state['mode'] == 'Light Mode' else 1)
23
-
24
- st.session_state['mode'] = mode
25
-
26
  # Custom CSS to improve styling and responsiveness
27
- def local_css(mode='Light Mode'):
28
- if mode == 'Light Mode':
29
- css_string = '''
30
  <style>
31
- /* Light mode CSS */
32
- body {
33
  background-color: #f0f2f6;
34
- color: #000000;
35
  }
36
  /* Title styling */
37
  .title h1 {
38
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
39
  text-align: center;
40
- color: #000000;
41
  font-size: 3rem;
42
  margin-bottom: 20px;
43
  }
44
  /* Image styling */
45
- img {
46
  border-radius: 15px;
47
  margin-bottom: 20px;
48
  max-width: 100%;
49
  }
50
  /* Sidebar styling */
51
  [data-testid="stSidebar"] {
52
- background-color: #ffffff;
53
- color: #000000;
 
 
 
 
 
54
  }
55
  /* File uploader styling */
56
  .stFileUploader {
57
- border: 2px dashed #000000;
58
  border-radius: 10px;
59
  padding: 20px;
60
  text-align: center;
61
- color: #000000;
62
  background-color: #ffffff;
63
  font-weight: bold;
64
  }
 
65
  .stFileUploader:hover {
66
- background-color: #e0e0e0;
67
  }
68
  /* Button styling */
69
- button {
70
- background-color: #000000 !important;
71
- color: #ffffff !important;
72
- border: none !important;
73
- padding: 0.7rem 1.5rem !important;
74
- border-radius: 5px !important;
75
- font-size: 1.1rem !important;
76
- font-weight: bold !important;
77
- margin-top: 10px !important;
78
- }
79
- button:hover {
80
- background-color: #333333 !important;
81
- color: #ffffff !important;
82
- }
83
- /* Headers styling */
84
- h2, h3 {
85
- color: #000000;
86
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
87
- }
88
- /* Text styling */
89
- p {
90
  font-size: 1.1rem;
91
- color: #000000;
92
- }
93
- /* Hide footer */
94
- footer {
95
- visibility: hidden;
96
- }
97
- /* Responsive Design */
98
- @media only screen and (max-width: 600px) {
99
- [data-testid="stSidebar"] {
100
- display: none;
101
- }
102
- .block-container {
103
- padding-left: 1rem;
104
- padding-right: 1rem;
105
- }
106
- .title h1 {
107
- font-size: 2rem;
108
- }
109
- button {
110
- width: 100% !important;
111
- }
112
- }
113
- /* Sample images grid */
114
- .sample-images {
115
- display: flex;
116
- justify-content: center;
117
- flex-wrap: wrap;
118
- gap: 10px;
119
- }
120
- .sample-images img {
121
- width: 150px;
122
- height: 150px;
123
- object-fit: cover;
124
- border-radius: 10px;
125
- cursor: pointer;
126
- border: 2px solid transparent;
127
- }
128
- .sample-images img:hover {
129
- border: 2px solid #000000;
130
- }
131
- </style>
132
- '''
133
- else:
134
- css_string = '''
135
- <style>
136
- /* Dark mode CSS */
137
- body {
138
- background-color: #1e1e1e;
139
- color: #ffffff;
140
- }
141
- /* Title styling */
142
- .title h1 {
143
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
144
- text-align: center;
145
- color: #ffffff;
146
- font-size: 3rem;
147
- margin-bottom: 20px;
148
- }
149
- /* Image styling */
150
- img {
151
- border-radius: 15px;
152
- margin-bottom: 20px;
153
- max-width: 100%;
154
- }
155
- /* Sidebar styling */
156
- [data-testid="stSidebar"] {
157
- background-color: #333333;
158
- color: #ffffff;
159
- }
160
- /* File uploader styling */
161
- .stFileUploader {
162
- border: 2px dashed #ffffff;
163
- border-radius: 10px;
164
- padding: 20px;
165
- text-align: center;
166
- color: #ffffff;
167
- background-color: #1e1e1e;
168
  font-weight: bold;
 
169
  }
170
- .stFileUploader:hover {
171
- background-color: #333333;
172
- }
173
- /* Button styling */
174
- button {
175
- background-color: #ffffff !important;
176
- color: #000000 !important;
177
- border: none !important;
178
- padding: 0.7rem 1.5rem !important;
179
- border-radius: 5px !important;
180
- font-size: 1.1rem !important;
181
- font-weight: bold !important;
182
- margin-top: 10px !important;
183
- }
184
- button:hover {
185
- background-color: #e0e0e0 !important;
186
- color: #000000 !important;
187
  }
188
  /* Headers styling */
189
- h2, h3 {
190
- color: #ffffff;
 
 
 
 
 
191
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
192
  }
193
  /* Text styling */
194
- p {
195
  font-size: 1.1rem;
196
- color: #ffffff;
197
  }
198
- /* Hide footer */
199
  footer {
200
  visibility: hidden;
201
  }
202
- /* Responsive Design */
203
  @media only screen and (max-width: 600px) {
204
  [data-testid="stSidebar"] {
205
  display: none;
206
  }
207
- .block-container {
208
  padding-left: 1rem;
209
  padding-right: 1rem;
210
  }
211
  .title h1 {
212
  font-size: 2rem;
213
  }
214
- button {
215
- width: 100% !important;
216
  }
217
  }
218
  /* Sample images grid */
@@ -231,14 +125,20 @@ def local_css(mode='Light Mode'):
231
  border: 2px solid transparent;
232
  }
233
  .sample-images img:hover {
234
- border: 2px solid #ffffff;
235
  }
236
  </style>
237
- '''
238
- st.markdown(css_string, unsafe_allow_html=True)
 
 
 
 
 
 
239
 
240
- # Apply the custom CSS based on the selected mode
241
- local_css(st.session_state['mode'])
242
 
243
  # Load the image classification pipeline
244
  @st.cache_resource
@@ -256,8 +156,6 @@ def get_ingredients_qwen(food_name):
256
  Generate a list of ingredients for the given food item using Qwen NLP model.
257
  Returns a clean, comma-separated list of ingredients.
258
  """
259
- API_KEY = st.secrets["HF_API_KEY"]
260
- client = InferenceClient(api_key=API_KEY)
261
  messages = [
262
  {
263
  "role": "user",
@@ -266,7 +164,7 @@ def get_ingredients_qwen(food_name):
266
  }
267
  ]
268
  try:
269
- completion = client.chat_completions.create(
270
  model="Qwen/Qwen2.5-Coder-32B-Instruct",
271
  messages=messages,
272
  max_tokens=50
@@ -302,54 +200,53 @@ sample_images = {
302
  }
303
 
304
  cols = st.columns(len(sample_images))
305
- selected_sample = None
306
  for idx, (name, file_path) in enumerate(sample_images.items()):
307
  with cols[idx]:
308
  if st.button(f"{name}", key=name):
309
- selected_sample = file_path
310
 
311
  # File uploader
312
  st.subheader("Upload a food image:")
313
  uploaded_file = st.file_uploader("", type=["jpg", "png", "jpeg"])
314
 
315
- if selected_sample:
316
- # Sample image selected
317
- image = Image.open(selected_sample)
318
- st.image(image, caption="Selected Sample Image", use_container_width=True)
319
- classify = st.button("Classify", key="classify_sample")
320
- elif uploaded_file is not None:
321
- # User uploaded image
322
- image = Image.open(uploaded_file)
323
  st.image(image, caption="Uploaded Image", use_container_width=True)
324
- classify = st.button("Classify", key="classify_upload")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  else:
326
  st.info("Please select or upload an image to get started.")
327
- classify = False
328
-
329
- if classify:
330
- with st.spinner("Classifying..."):
331
- # Make predictions
332
- predictions = pipe_classification(image)
333
-
334
- # Display only the top prediction
335
- top_food = predictions[0]['label']
336
- st.header(f"🍽️ Food: {top_food}")
337
-
338
- # Generate and display ingredients for the top prediction
339
- st.subheader("📝 Ingredients")
340
- try:
341
- ingredients = get_ingredients_qwen(top_food)
342
- st.write(ingredients)
343
- except Exception as e:
344
- st.error(f"Error generating ingredients: {e}")
345
 
346
- st.subheader("💡 Healthier Alternatives")
347
- try:
348
- client_gradio = Client("https://8a56cb969da1f9d721.gradio.live/")
349
- result = client_gradio.predict(
350
- query=f"What's a healthy {top_food} recipe, and why is it healthy?",
351
- api_name="/get_response"
352
- )
353
- st.write(result)
354
- except Exception as e:
355
- st.error(f"Unable to contact RAG: {e}")
 
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;
 
24
  }
25
  /* Title styling */
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
  }
33
  /* Image styling */
34
+ .st-image img {
35
  border-radius: 15px;
36
  margin-bottom: 20px;
37
  max-width: 100%;
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;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  font-size: 1.1rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  font-weight: bold;
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 {
94
  visibility: hidden;
95
  }
96
+ /* Hide sidebar on small screens */
97
  @media only screen and (max-width: 600px) {
98
  [data-testid="stSidebar"] {
99
  display: none;
100
  }
101
+ .main .block-container {
102
  padding-left: 1rem;
103
  padding-right: 1rem;
104
  }
105
  .title h1 {
106
  font-size: 2rem;
107
  }
108
+ .stButton>button {
109
+ width: 100%;
110
  }
111
  }
112
  /* Sample images grid */
 
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
  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
  }
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
  }
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