Liori25 commited on
Commit
314d63a
·
verified ·
1 Parent(s): 742ad34

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -13
app.py CHANGED
@@ -4,13 +4,12 @@ import pickle
4
  import numpy as np
5
  import os
6
  import random
7
- import traceback
8
  from huggingface_hub import InferenceClient
9
  from sklearn.metrics.pairwise import cosine_similarity
10
  from IO_pipeline import RecipeDigitalizerPipeline
11
 
12
  # ==========================================
13
- # 1. DATA LOADING & SETUP
14
  # ==========================================
15
  hf_token = os.getenv("HF_TOKEN")
16
  API_MODEL = "BAAI/bge-small-en-v1.5"
@@ -25,6 +24,7 @@ try:
25
  if isinstance(data, dict):
26
  stored_embeddings = np.array(data['embeddings'])
27
  elif isinstance(data, pd.DataFrame):
 
28
  target_col = next((c for c in ['embedding', 'embeddings', 'vectors'] if c in data.columns), None)
29
  stored_embeddings = np.vstack(data[target_col].values) if target_col else data
30
  else:
@@ -36,7 +36,7 @@ except Exception as e:
36
  stored_embeddings = None
37
 
38
  # ==========================================
39
- # 2. BACKEND LOGIC
40
  # ==========================================
41
  def get_embedding_via_api(text):
42
  if not client: raise ValueError("HF_TOKEN missing")
@@ -45,7 +45,6 @@ def get_embedding_via_api(text):
45
 
46
  def find_similar_recipes(query_text):
47
  if stored_embeddings is None: return "Database error."
48
-
49
  query_vec = get_embedding_via_api("Represent this recipe for retrieving similar dishes: " + query_text)
50
  if len(query_vec.shape) == 1: query_vec = query_vec.reshape(1, -1)
51
 
@@ -80,30 +79,149 @@ def magic_pipeline(image_path):
80
  return f"Error: {e}", f"Error: {e}"
81
 
82
  # ==========================================
83
- # 3. UI STYLING (The "Facebook" Look)
84
  # ==========================================
85
  fb_css = """
86
- body {background-color: #f0f2f5 !important; font-family: 'Segoe UI', Helvetica, Arial, sans-serif;}
87
 
88
- /* Header */
89
  .fb-header {
90
  background-color: #ffffff;
91
  color: #1877f2;
92
- padding: 10px 20px;
93
  font-size: 28px;
94
  font-weight: 900;
95
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
96
- margin-bottom: 20px;
97
  border-bottom: 1px solid #ddd;
 
 
 
98
  }
99
 
100
- /* Sidebar Styling */
101
- .sidebar-container {
102
- padding-right: 10px;
 
103
  }
 
104
  .sidebar-btn {
105
  background-color: transparent !important;
106
  color: #050505 !important;
107
  text-align: left !important;
108
  border: none !important;
109
- font
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  import numpy as np
5
  import os
6
  import random
 
7
  from huggingface_hub import InferenceClient
8
  from sklearn.metrics.pairwise import cosine_similarity
9
  from IO_pipeline import RecipeDigitalizerPipeline
10
 
11
  # ==========================================
12
+ # 1. SETUP & DATA LOADING
13
  # ==========================================
14
  hf_token = os.getenv("HF_TOKEN")
15
  API_MODEL = "BAAI/bge-small-en-v1.5"
 
24
  if isinstance(data, dict):
25
  stored_embeddings = np.array(data['embeddings'])
26
  elif isinstance(data, pd.DataFrame):
27
+ # Fallback for dataframe format
28
  target_col = next((c for c in ['embedding', 'embeddings', 'vectors'] if c in data.columns), None)
29
  stored_embeddings = np.vstack(data[target_col].values) if target_col else data
30
  else:
 
36
  stored_embeddings = None
37
 
38
  # ==========================================
39
+ # 2. LOGIC
40
  # ==========================================
41
  def get_embedding_via_api(text):
42
  if not client: raise ValueError("HF_TOKEN missing")
 
45
 
46
  def find_similar_recipes(query_text):
47
  if stored_embeddings is None: return "Database error."
 
48
  query_vec = get_embedding_via_api("Represent this recipe for retrieving similar dishes: " + query_text)
49
  if len(query_vec.shape) == 1: query_vec = query_vec.reshape(1, -1)
50
 
 
79
  return f"Error: {e}", f"Error: {e}"
80
 
81
  # ==========================================
82
+ # 3. CSS STYLING (With Logo Support)
83
  # ==========================================
84
  fb_css = """
85
+ body {background-color: #f0f2f5 !important; font-family: Helvetica, Arial, sans-serif;}
86
 
 
87
  .fb-header {
88
  background-color: #ffffff;
89
  color: #1877f2;
90
+ padding: 10px 20px;
91
  font-size: 28px;
92
  font-weight: 900;
93
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
 
94
  border-bottom: 1px solid #ddd;
95
+ margin-bottom: 20px;
96
+ display: flex;
97
+ align-items: center;
98
  }
99
 
100
+ .logo-img {
101
+ height: 40px;
102
+ margin-right: 15px;
103
+ border-radius: 5px;
104
  }
105
+
106
  .sidebar-btn {
107
  background-color: transparent !important;
108
  color: #050505 !important;
109
  text-align: left !important;
110
  border: none !important;
111
+ font-weight: 600 !important;
112
+ padding: 12px !important;
113
+ font-size: 16px !important;
114
+ box-shadow: none !important;
115
+ width: 100% !important;
116
+ border-radius: 8px !important;
117
+ }
118
+ .sidebar-btn:hover { background-color: #e4e6eb !important; }
119
+
120
+ .fb-card {
121
+ background: white;
122
+ border-radius: 8px;
123
+ box-shadow: 0 1px 2px rgba(0,0,0,0.2);
124
+ padding: 20px;
125
+ margin-bottom: 20px;
126
+ }
127
+
128
+ .avatar {
129
+ width: 40px; height: 40px;
130
+ background-color: #e4e6eb;
131
+ border-radius: 50%;
132
+ text-align: center;
133
+ line-height: 40px;
134
+ margin-right: 10px;
135
+ }
136
+ """
137
+
138
+ # ==========================================
139
+ # 4. LAYOUT
140
+ # ==========================================
141
+ with gr.Blocks(css=fb_css, title="Legacy Kitchen") as demo:
142
+
143
+ # --- HEADER WITH LOGO ---
144
+ # We use 'file/logo.jpg' to access local files in Gradio/HF Spaces
145
+ gr.HTML("""
146
+ <div class="fb-header">
147
+ <img src="file/logo.jpg" class="logo-img" alt="Logo">
148
+ Legacy Kitchen
149
+ </div>
150
+ """)
151
+
152
+ with gr.Row():
153
+
154
+ # --- LEFT SIDEBAR ---
155
+ with gr.Column(scale=1, min_width=250):
156
+ gr.HTML('<div style="display:flex; align-items:center; margin-bottom:20px;"><div class="avatar">👤</div><b>My Profile</b></div>')
157
+
158
+ nav_feed = gr.Button("📰 Feed", elem_classes=["sidebar-btn"])
159
+ nav_digital = gr.Button("📸 Digitizer", elem_classes=["sidebar-btn"])
160
+ nav_saved = gr.Button("🔖 Saved", elem_classes=["sidebar-btn"])
161
+
162
+ gr.Markdown("---")
163
+ gr.Markdown("Privacy · Terms · Cookies")
164
+
165
+ # --- RIGHT CONTENT ---
166
+ with gr.Column(scale=3):
167
+
168
+ # VIEW 1: FEED
169
+ with gr.Group(visible=True) as feed_view:
170
+ with gr.Group(elem_classes=["fb-card"]):
171
+ with gr.Row():
172
+ gr.HTML('<div class="avatar">👤</div>')
173
+ gr.Textbox(placeholder="What's cooking?", show_label=False, container=False, scale=5)
174
+
175
+ if not df_recipes.empty:
176
+ feed_samples = df_recipes.sample(10)
177
+ for index, row in feed_samples.iterrows():
178
+ with gr.Group(elem_classes=["fb-card"]):
179
+ user = random.choice(["Grandma Rose", "Chef Mike", "Sarah J."])
180
+ emoji = random.choice(["🥘", "🥗", "🍰"])
181
+
182
+ gr.HTML(f"""
183
+ <div style="display:flex; margin-bottom:10px;">
184
+ <div class="avatar">{emoji}</div>
185
+ <div><b>{user}</b><br><span style="color:gray; font-size:12px;">2h · 🌍</span></div>
186
+ </div>
187
+ """)
188
+
189
+ gr.Markdown(f"**{row['Title']}**\n\n{str(row['Raw_Output'])[:200]}... [Read More]")
190
+
191
+ with gr.Row():
192
+ like_btn = gr.Button("👍 Like", size="sm")
193
+ gr.Button("💬 Comment", size="sm")
194
+ gr.Button("↗️ Share", size="sm")
195
+
196
+ def toggle_like(x): return "👍 Liked!"
197
+ like_btn.click(toggle_like, like_btn, like_btn)
198
+ else:
199
+ gr.Markdown("Database empty.")
200
+
201
+ # VIEW 2: DIGITALIZER
202
+ with gr.Group(visible=False) as digitalizer_view:
203
+ gr.Markdown("### 📸 Digitize Recipe", elem_classes=["fb-card"])
204
+
205
+ with gr.Group(elem_classes=["fb-card"]):
206
+ with gr.Row():
207
+ with gr.Column():
208
+ input_img = gr.Image(type="filepath", label="Upload Photo")
209
+ magic_btn = gr.Button("✨ Digitize", variant="primary")
210
+ with gr.Column():
211
+ out_text = gr.Textbox(label="Text", lines=10)
212
+ out_sim = gr.Textbox(label="Similar", lines=10)
213
+
214
+ magic_btn.click(magic_pipeline, input_img, [out_text, out_sim])
215
+
216
+ # VIEW 3: SAVED
217
+ with gr.Group(visible=False) as saved_view:
218
+ gr.Markdown("### 🔖 Saved Recipes", elem_classes=["fb-card"])
219
+ gr.Markdown("No saved recipes yet.")
220
+
221
+ # Nav Logic
222
+ nav_feed.click(lambda: (gr.update(visible=True), gr.update(visible=False), gr.update(visible=False)), None, [feed_view, digitalizer_view, saved_view])
223
+ nav_digital.click(lambda: (gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)), None, [feed_view, digitalizer_view, saved_view])
224
+ nav_saved.click(lambda: (gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)), None, [feed_view, digitalizer_view, saved_view])
225
+
226
+ if __name__ == "__main__":
227
+ demo.launch()