OmPrakashSingh1704 commited on
Commit
f45a4ae
1 Parent(s): 64b77e4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +286 -279
app.py CHANGED
@@ -4,10 +4,7 @@ import re, ast, secrets, os, json
4
  import pandas as pd
5
  from huggingface_hub import login, InferenceClient
6
  import pickle,datetime
7
- from functools import partial
8
  from sklearn.metrics.pairwise import cosine_similarity
9
- import datetime
10
-
11
 
12
  st.set_page_config(layout="wide")
13
 
@@ -56,296 +53,306 @@ def show_recipe(recipe):
56
  # Initialize the inference client for the Mixtral model
57
 
58
  if not mode:
 
 
 
59
  cook,saved=st.tabs(['COOK','SAVED'])
60
- with cook:
61
- client = InferenceClient("mistralai/Mixtral-8x7B-Instruct-v0.1")
62
-
63
- if 'recipe' not in st.session_state:
64
- st.session_state.recipe = None
65
-
66
- if 'recipe_saved' not in st.session_state:
67
- st.session_state.recipe_saved = None
68
-
69
- if 'user_direction' not in st.session_state:
70
- st.session_state.user_direction = None
71
-
72
- if 'serving_size' not in st.session_state:
73
- st.session_state.serving_size = 2
74
-
75
- if 'selected_difficulty' not in st.session_state:
76
- st.session_state.selected_difficulty = "Quick & Easy"
77
-
78
- if 'exclusions' not in st.session_state:
79
- st.session_state.exclusions = None
80
-
81
- def preprocess_text(text):
82
- # Remove non-alphabet characters and extra spaces
83
- text = re.sub(r'[^a-zA-Z\s]', '', text)
84
- text = re.sub(r'\s+', ' ', text).strip()
85
- return text.lower()
86
-
87
- def create_detailed_prompt(user_direction, exclusions, serving_size, difficulty):
88
- if difficulty == "Quick & Easy":
89
- prompt = (
90
- f"Provide a 'Quick and Easy' recipe for {user_direction} that excludes {exclusions} and has a serving size of {serving_size}. "
91
- f"It should require as few ingredients as possible and should be ready in as little time as possible. "
92
- f"The steps should be simple, and the ingredients should be commonly found in a household pantry. "
93
- f"Provide a detailed ingredient list and step-by-step guide that explains the instructions to prepare in detail."
94
- )
95
- elif difficulty == "Intermediate":
96
- prompt = (
97
- f"Provide a classic recipe for {user_direction} that excludes {exclusions} and has a serving size of {serving_size}. "
98
- f"The recipe should offer a bit of a cooking challenge but should not require professional skills. "
99
- f"The recipe should feature traditional ingredients and techniques that are authentic to its cuisine. "
100
- f"Provide a detailed ingredient list and step-by-step guide that explains the instructions to prepare in detail."
101
- )
102
- elif difficulty == "Professional":
103
- prompt = (
104
- f"Provide an advanced recipe for {user_direction} that excludes {exclusions} and has a serving size of {serving_size}. "
105
- f"The recipe should push the boundaries of culinary arts, integrating unique ingredients, advanced cooking techniques, and innovative presentations. "
106
- f"The recipe should be able to be served at a high-end restaurant or would impress at a gourmet food competition. "
107
- f"Provide a detailed ingredient list and step-by-step guide that explains the instructions to prepare in detail."
108
- )
109
- return prompt
110
-
111
-
112
- def generate_recipe(user_inputs):
113
- with st.spinner('Building the perfect recipe...'):
114
- prompt = create_detailed_prompt(user_inputs['user_direction'], user_inputs['exclusions'],
115
- user_inputs['serving_size'], user_inputs['difficulty'])
116
-
117
- functions = [
118
- {
119
- "name": "provide_recipe",
120
- "description": "Provides a detailed recipe strictly adhering to the user input/specifications, especially ingredient exclusions and the recipe difficulty",
121
- "parameters": {
122
- "type": "object",
123
- "properties": {
124
- "name": {
125
- "type": "string",
126
- "description": "A creative name for the recipe"
127
- },
128
- "description": {
129
- "type": "string",
130
- "description": "a brief one-sentence description of the provided recipe"
131
- },
132
- "ingredients": {
133
- "type": "array",
134
- "items": {
135
- "type": "object",
136
- "properties": {
137
- "name": {
138
- "type": "string",
139
- "description": "Quantity and name of the ingredient"
 
 
 
 
 
 
 
140
  }
141
  }
142
- }
143
- },
144
- "instructions": {
145
- "type": "array",
146
- "items": {
147
- "type": "object",
148
- "properties": {
149
- "step_number": {
150
- "type": "number",
151
- "description": "The sequence number of this step"
152
- },
153
- "instruction": {
154
- "type": "string",
155
- "description": "Detailed description of what to do in this step"
156
  }
157
  }
158
  }
159
- }
 
 
 
 
 
 
160
  },
161
- "required": [
162
- "name",
163
- "description",
164
- "ingredients",
165
- "instructions"
166
- ],
167
- },
168
- }
169
- ]
170
-
171
- generate_kwargs = dict(
172
- temperature=0.9,
173
- max_new_tokens=10000,
174
- top_p=0.9,
175
- repetition_penalty=1.0,
176
- do_sample=True,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  )
178
-
179
- prompt += f"\nPlease format the output in JSON. The JSON should include fields for 'name', 'description', 'ingredients', and 'instructions', with each field structured as described below.\n\n{json.dumps(functions)}"
180
-
181
- response = client.text_generation(prompt, **generate_kwargs)
182
- st.session_state.recipe = response
183
- st.session_state.recipe_saved = False
184
-
185
-
186
- def clear_inputs():
187
- st.session_state.user_direction = None
188
- st.session_state.exclusions = None
189
- st.session_state.serving_size = 2
190
- st.session_state.selected_difficulty = "Quick & Easy"
191
- st.session_state.recipe=None
192
-
193
-
194
- st.title("Let's get cooking")
195
- col1,col2=st.columns(2)
196
- with col1:
197
- st.session_state.user_direction = st.text_area(
198
- "What do you want to cook? Describe anything - a dish, cuisine, event, or vibe.",
199
- value=st.session_state.user_direction,
200
- placeholder="quick snack, asian style bowl with either noodles or rice, something italian",
 
 
 
 
 
 
 
 
 
 
 
201
  )
202
- with col2:
203
- st.session_state.serving_size = st.number_input(
204
- "How many servings would you like to cook?",
205
- min_value=1,
206
- max_value=100,
207
- value=st.session_state.serving_size,
208
- step=1
209
  )
210
-
211
- difficulty_dictionary = {
212
- "Quick & Easy": {
213
- "description": "Easy recipes with straightforward instructions. Ideal for beginners or those seeking quick and simple cooking.",
214
- },
215
- "Intermediate": {
216
- "description": "Recipes with some intricate steps that invite a little challenge. Perfect for regular cooks wanting to expand their repertoire with new ingredients and techniques.",
217
- },
218
- "Professional": {
219
- "description": "Complex recipes that demand a high level of skill and precision. Suited for seasoned cooks aspiring to professional-level sophistication and creativity.",
 
 
 
 
 
220
  }
221
- }
222
-
223
- st.session_state.selected_difficulty = st.radio(
224
- "Choose a difficulty level for your recipe.",
225
- [
226
- list(difficulty_dictionary.keys())[0],
227
- list(difficulty_dictionary.keys())[1],
228
- list(difficulty_dictionary.keys())[2]
229
- ],
230
- captions=[
231
- difficulty_dictionary["Quick & Easy"]["description"],
232
- difficulty_dictionary["Intermediate"]["description"],
233
- difficulty_dictionary["Professional"]["description"]
234
- ],
235
- index=list(difficulty_dictionary).index(st.session_state.selected_difficulty)
236
- )
237
-
238
- st.session_state.exclusions = st.text_area(
239
- "Any ingredients you want to exclude?",
240
- value=st.session_state.exclusions,
241
- placeholder="gluten, dairy, nuts, cilantro",
242
- )
243
-
244
- fancy_exclusions = ""
245
-
246
- if st.session_state.selected_difficulty == "Professional":
247
- exclude_fancy = st.checkbox(
248
- "Exclude cliche professional ingredients? (gold leaf, truffle, edible flowers, microgreens)",
249
- value=True)
250
- if exclude_fancy:
251
- fancy_exclusions = "gold leaf, truffle, edible flowers, microgreens, gold dust"
252
-
253
- user_inputs = {
254
- "user_direction": st.session_state.user_direction,
255
- "exclusions": f"{st.session_state.exclusions}, {fancy_exclusions}".strip(", "),
256
- "serving_size": st.session_state.serving_size,
257
- "difficulty": st.session_state.selected_difficulty
258
- }
259
-
260
- button_cols_submit = st.columns([1, 1, 4])
261
- with button_cols_submit[0]:
262
- st.button(label='Submit', on_click=generate_recipe, kwargs=dict(user_inputs=user_inputs), type="primary",
263
- use_container_width=True)
264
- with button_cols_submit[1]:
265
- st.button(label='Reset', on_click=clear_inputs, type="secondary", use_container_width=True)
266
- with button_cols_submit[2]:
267
- st.empty()
268
-
269
- def create_safe_filename(recipe_name):
270
- # format and generate random URL-safe text string
271
- safe_name = recipe_name.lower()
272
- safe_name = safe_name.replace(" ", "_")
273
- safe_name = re.sub(r"[^a-zA-Z0-9_]", "", safe_name)
274
- safe_name = (safe_name[:50]) if len(safe_name) > 50 else safe_name
275
- unique_token = secrets.token_hex(8)
276
- safe_filename = f"{unique_token}_{safe_name}"
277
- return safe_filename
278
-
279
- def save_recipe():
280
- with st.spinner('WAIT SAVING YOUR DISH...'):
281
- filename = create_safe_filename(recipe["name"])
282
- os.makedirs('data', exist_ok=True)
283
- with open(f'./data/{filename}.pkl', 'wb') as f:
284
- pickle.dump(recipe, f)
285
- st.session_state.recipe_saved = True
286
-
287
- if st.session_state.recipe is not None:
288
- st.divider()
289
- print(st.session_state.recipe)
290
- recipe = json.loads(st.session_state.recipe)
291
- show_recipe(recipe)
292
- recipe['timestamp'] = str(datetime.datetime.now())
293
- if st.session_state.recipe_saved == True:
294
- disable_button = True
295
- else:
296
- disable_button = False
297
- button_cols_save = st.columns([1, 1, 4])
298
- with button_cols_save[0]:
299
- st.button("Save Recipe", on_click=save_recipe, disabled=disable_button, type="primary")
300
- with button_cols_save[1]:
301
- st.empty()
302
- with button_cols_save[2]:
303
  st.empty()
304
- if st.session_state.recipe_saved == True:
305
- st.success("Recipe Saved!")
306
- with saved:
307
- st.title("Saved Recipes")
308
- with st.spinner('LOADING YOUR RECIPE...'):
309
- def load_saved_recipes_from_pickle(directory_path):
310
- os.makedirs('data', exist_ok=True)
311
- recipes = []
312
- # Iterate through all files in the directory
313
- for filename in os.listdir(directory_path):
314
- if filename.endswith('.pkl'):
315
- file_path = os.path.join(directory_path, filename)
316
- with open(file_path, 'rb') as file:
317
- recipe = pickle.load(file)
318
- recipes.append(recipe)
319
- return recipes
320
-
321
 
322
- # get all saved files
323
- directory_path = 'data'
324
- recipes = load_saved_recipes_from_pickle(directory_path)
325
- print(recipes)
 
 
 
 
 
326
 
327
- cols = st.columns([4, 1])
328
- with cols[1]:
329
- user_sort = st.selectbox("Sort", ('Recent', 'Oldest', 'A-Z', 'Z-A', 'Random'))
330
- if user_sort == 'Recent':
331
- recipes.sort(key=lambda x: x['timestamp'], reverse=True)
332
- elif user_sort == 'Oldest':
333
- recipes.sort(key=lambda x: x['timestamp'])
334
- elif user_sort == 'A-Z':
335
- recipes.sort(key=lambda x: x['name'])
336
- elif user_sort == 'Z-A':
337
- recipes.sort(key=lambda x: x['name'], reverse=True)
338
- elif user_sort == 'Random':
339
- recipes.sort(key=lambda x: x['file'])
340
- with cols[0]:
341
- user_search = st.selectbox("Search Recipes", [""] + [recipe['name'] for recipe in recipes])
342
- st.write("") # just some space
343
 
344
- if user_search!="":
345
  st.divider()
346
- filtered_recipes = [recipe for recipe in recipes if recipe['name'] == user_search]
347
- if filtered_recipes:
348
- show_recipe(filtered_recipes[0])
 
 
 
 
349
  else:
350
- st.write("No recipe found.")
351
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  import pandas as pd
5
  from huggingface_hub import login, InferenceClient
6
  import pickle,datetime
 
7
  from sklearn.metrics.pairwise import cosine_similarity
 
 
8
 
9
  st.set_page_config(layout="wide")
10
 
 
53
  # Initialize the inference client for the Mixtral model
54
 
55
  if not mode:
56
+ if 'current_tab' not in st.session_state:
57
+ st.session_state.current_tab = 'COOK'
58
+
59
  cook,saved=st.tabs(['COOK','SAVED'])
60
+
61
+ if cook:
62
+ st.session_state.current_tab = 'COOK'
63
+ if saved:
64
+ st.session_state.current_tab = 'SAVED'
65
+ if st.session_state.current_tab == 'COOK':
66
+ with cook:
67
+ client = InferenceClient("mistralai/Mixtral-8x7B-Instruct-v0.1")
68
+
69
+ if 'recipe' not in st.session_state:
70
+ st.session_state.recipe = None
71
+
72
+ if 'recipe_saved' not in st.session_state:
73
+ st.session_state.recipe_saved = None
74
+
75
+ if 'user_direction' not in st.session_state:
76
+ st.session_state.user_direction = None
77
+
78
+ if 'serving_size' not in st.session_state:
79
+ st.session_state.serving_size = 2
80
+
81
+ if 'selected_difficulty' not in st.session_state:
82
+ st.session_state.selected_difficulty = "Quick & Easy"
83
+
84
+ if 'exclusions' not in st.session_state:
85
+ st.session_state.exclusions = None
86
+
87
+ def preprocess_text(text):
88
+ # Remove non-alphabet characters and extra spaces
89
+ text = re.sub(r'[^a-zA-Z\s]', '', text)
90
+ text = re.sub(r'\s+', ' ', text).strip()
91
+ return text.lower()
92
+
93
+ def create_detailed_prompt(user_direction, exclusions, serving_size, difficulty):
94
+ if difficulty == "Quick & Easy":
95
+ prompt = (
96
+ f"Provide a 'Quick and Easy' recipe for {user_direction} that excludes {exclusions} and has a serving size of {serving_size}. "
97
+ f"It should require as few ingredients as possible and should be ready in as little time as possible. "
98
+ f"The steps should be simple, and the ingredients should be commonly found in a household pantry. "
99
+ f"Provide a detailed ingredient list and step-by-step guide that explains the instructions to prepare in detail."
100
+ )
101
+ elif difficulty == "Intermediate":
102
+ prompt = (
103
+ f"Provide a classic recipe for {user_direction} that excludes {exclusions} and has a serving size of {serving_size}. "
104
+ f"The recipe should offer a bit of a cooking challenge but should not require professional skills. "
105
+ f"The recipe should feature traditional ingredients and techniques that are authentic to its cuisine. "
106
+ f"Provide a detailed ingredient list and step-by-step guide that explains the instructions to prepare in detail."
107
+ )
108
+ elif difficulty == "Professional":
109
+ prompt = (
110
+ f"Provide an advanced recipe for {user_direction} that excludes {exclusions} and has a serving size of {serving_size}. "
111
+ f"The recipe should push the boundaries of culinary arts, integrating unique ingredients, advanced cooking techniques, and innovative presentations. "
112
+ f"The recipe should be able to be served at a high-end restaurant or would impress at a gourmet food competition. "
113
+ f"Provide a detailed ingredient list and step-by-step guide that explains the instructions to prepare in detail."
114
+ )
115
+ return prompt
116
+
117
+
118
+ def generate_recipe(user_inputs):
119
+ with st.spinner('Building the perfect recipe...'):
120
+ prompt = create_detailed_prompt(user_inputs['user_direction'], user_inputs['exclusions'],
121
+ user_inputs['serving_size'], user_inputs['difficulty'])
122
+
123
+ functions = [
124
+ {
125
+ "name": "provide_recipe",
126
+ "description": "Provides a detailed recipe strictly adhering to the user input/specifications, especially ingredient exclusions and the recipe difficulty",
127
+ "parameters": {
128
+ "type": "object",
129
+ "properties": {
130
+ "name": {
131
+ "type": "string",
132
+ "description": "A creative name for the recipe"
133
+ },
134
+ "description": {
135
+ "type": "string",
136
+ "description": "a brief one-sentence description of the provided recipe"
137
+ },
138
+ "ingredients": {
139
+ "type": "array",
140
+ "items": {
141
+ "type": "object",
142
+ "properties": {
143
+ "name": {
144
+ "type": "string",
145
+ "description": "Quantity and name of the ingredient"
146
+ }
147
  }
148
  }
149
+ },
150
+ "instructions": {
151
+ "type": "array",
152
+ "items": {
153
+ "type": "object",
154
+ "properties": {
155
+ "step_number": {
156
+ "type": "number",
157
+ "description": "The sequence number of this step"
158
+ },
159
+ "instruction": {
160
+ "type": "string",
161
+ "description": "Detailed description of what to do in this step"
162
+ }
163
  }
164
  }
165
  }
166
+ },
167
+ "required": [
168
+ "name",
169
+ "description",
170
+ "ingredients",
171
+ "instructions"
172
+ ],
173
  },
174
+ }
175
+ ]
176
+
177
+ generate_kwargs = dict(
178
+ temperature=0.9,
179
+ max_new_tokens=10000,
180
+ top_p=0.9,
181
+ repetition_penalty=1.0,
182
+ do_sample=True,
183
+ )
184
+
185
+ prompt += f"\nPlease format the output in JSON. The JSON should include fields for 'name', 'description', 'ingredients', and 'instructions', with each field structured as described below.\n\n{json.dumps(functions)}"
186
+
187
+ response = client.text_generation(prompt, **generate_kwargs)
188
+ st.session_state.recipe = response
189
+ st.session_state.recipe_saved = False
190
+
191
+
192
+ def clear_inputs():
193
+ st.session_state.user_direction = None
194
+ st.session_state.exclusions = None
195
+ st.session_state.serving_size = 2
196
+ st.session_state.selected_difficulty = "Quick & Easy"
197
+ st.session_state.recipe=None
198
+
199
+
200
+ st.title("Let's get cooking")
201
+ col1,col2=st.columns(2)
202
+ with col1:
203
+ st.session_state.user_direction = st.text_area(
204
+ "What do you want to cook? Describe anything - a dish, cuisine, event, or vibe.",
205
+ value=st.session_state.user_direction,
206
+ placeholder="quick snack, asian style bowl with either noodles or rice, something italian",
207
  )
208
+ with col2:
209
+ st.session_state.serving_size = st.number_input(
210
+ "How many servings would you like to cook?",
211
+ min_value=1,
212
+ max_value=100,
213
+ value=st.session_state.serving_size,
214
+ step=1
215
+ )
216
+
217
+ difficulty_dictionary = {
218
+ "Quick & Easy": {
219
+ "description": "Easy recipes with straightforward instructions. Ideal for beginners or those seeking quick and simple cooking.",
220
+ },
221
+ "Intermediate": {
222
+ "description": "Recipes with some intricate steps that invite a little challenge. Perfect for regular cooks wanting to expand their repertoire with new ingredients and techniques.",
223
+ },
224
+ "Professional": {
225
+ "description": "Complex recipes that demand a high level of skill and precision. Suited for seasoned cooks aspiring to professional-level sophistication and creativity.",
226
+ }
227
+ }
228
+
229
+ st.session_state.selected_difficulty = st.radio(
230
+ "Choose a difficulty level for your recipe.",
231
+ [
232
+ list(difficulty_dictionary.keys())[0],
233
+ list(difficulty_dictionary.keys())[1],
234
+ list(difficulty_dictionary.keys())[2]
235
+ ],
236
+ captions=[
237
+ difficulty_dictionary["Quick & Easy"]["description"],
238
+ difficulty_dictionary["Intermediate"]["description"],
239
+ difficulty_dictionary["Professional"]["description"]
240
+ ],
241
+ index=list(difficulty_dictionary).index(st.session_state.selected_difficulty)
242
  )
243
+
244
+ st.session_state.exclusions = st.text_area(
245
+ "Any ingredients you want to exclude?",
246
+ value=st.session_state.exclusions,
247
+ placeholder="gluten, dairy, nuts, cilantro",
 
 
248
  )
249
+
250
+ fancy_exclusions = ""
251
+
252
+ if st.session_state.selected_difficulty == "Professional":
253
+ exclude_fancy = st.checkbox(
254
+ "Exclude cliche professional ingredients? (gold leaf, truffle, edible flowers, microgreens)",
255
+ value=True)
256
+ if exclude_fancy:
257
+ fancy_exclusions = "gold leaf, truffle, edible flowers, microgreens, gold dust"
258
+
259
+ user_inputs = {
260
+ "user_direction": st.session_state.user_direction,
261
+ "exclusions": f"{st.session_state.exclusions}, {fancy_exclusions}".strip(", "),
262
+ "serving_size": st.session_state.serving_size,
263
+ "difficulty": st.session_state.selected_difficulty
264
  }
265
+
266
+ button_cols_submit = st.columns([1, 1, 4])
267
+ with button_cols_submit[0]:
268
+ st.button(label='Submit', on_click=generate_recipe, kwargs=dict(user_inputs=user_inputs), type="primary",
269
+ use_container_width=True)
270
+ with button_cols_submit[1]:
271
+ st.button(label='Reset', on_click=clear_inputs, type="secondary", use_container_width=True)
272
+ with button_cols_submit[2]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
  st.empty()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
 
275
+ def create_safe_filename(recipe_name):
276
+ # format and generate random URL-safe text string
277
+ safe_name = recipe_name.lower()
278
+ safe_name = safe_name.replace(" ", "_")
279
+ safe_name = re.sub(r"[^a-zA-Z0-9_]", "", safe_name)
280
+ safe_name = (safe_name[:50]) if len(safe_name) > 50 else safe_name
281
+ unique_token = secrets.token_hex(8)
282
+ safe_filename = f"{unique_token}_{safe_name}"
283
+ return safe_filename
284
 
285
+ def save_recipe():
286
+ with st.spinner('WAIT SAVING YOUR DISH...'):
287
+ filename = create_safe_filename(recipe["name"])
288
+ os.makedirs('data', exist_ok=True)
289
+ with open(f'./data/{filename}.pkl', 'wb') as f:
290
+ pickle.dump(recipe, f)
291
+ st.session_state.recipe_saved = True
 
 
 
 
 
 
 
 
 
292
 
293
+ if st.session_state.recipe is not None:
294
  st.divider()
295
+ print(st.session_state.recipe)
296
+ recipe = json.loads(st.session_state.recipe)
297
+ if not st.session_state.recipe_saved:
298
+ show_recipe(recipe)
299
+ recipe['timestamp'] = str(datetime.datetime.now())
300
+ if st.session_state.recipe_saved == True:
301
+ disable_button = True
302
  else:
303
+ disable_button = False
304
+ button_cols_save = st.columns([1, 1, 4])
305
+ with button_cols_save[0]:
306
+ st.button("Save Recipe", on_click=save_recipe, disabled=disable_button, type="primary")
307
+ with button_cols_save[1]:
308
+ st.empty()
309
+ with button_cols_save[2]:
310
+ st.empty()
311
+ if st.session_state.recipe_saved == True:
312
+ st.success("Recipe Saved!")
313
+ if st.session_state.current_tab == 'SAVED':
314
+ with saved:
315
+ st.title("Saved Recipes")
316
+ with st.spinner('LOADING YOUR RECIPE...'):
317
+ def load_saved_recipes_from_pickle(directory_path):
318
+ os.makedirs('data', exist_ok=True)
319
+ recipes = []
320
+ # Iterate through all files in the directory
321
+ for filename in os.listdir(directory_path):
322
+ if filename.endswith('.pkl'):
323
+ file_path = os.path.join(directory_path, filename)
324
+ with open(file_path, 'rb') as file:
325
+ recipe = pickle.load(file)
326
+ recipes.append(recipe)
327
+ return recipes
328
+
329
+
330
+ # get all saved files
331
+ directory_path = 'data'
332
+ recipes = load_saved_recipes_from_pickle(directory_path)
333
+ print(recipes)
334
+
335
+ cols = st.columns([4, 1])
336
+ with cols[1]:
337
+ user_sort = st.selectbox("Sort", ('Recent', 'Oldest', 'A-Z', 'Z-A', 'Random'))
338
+ if user_sort == 'Recent':
339
+ recipes.sort(key=lambda x: x['timestamp'], reverse=True)
340
+ elif user_sort == 'Oldest':
341
+ recipes.sort(key=lambda x: x['timestamp'])
342
+ elif user_sort == 'A-Z':
343
+ recipes.sort(key=lambda x: x['name'])
344
+ elif user_sort == 'Z-A':
345
+ recipes.sort(key=lambda x: x['name'], reverse=True)
346
+ elif user_sort == 'Random':
347
+ recipes.sort(key=lambda x: x['file'])
348
+ with cols[0]:
349
+ user_search = st.selectbox("Search Recipes", [""] + [recipe['name'] for recipe in recipes])
350
+ st.write("") # just some space
351
+
352
+ if user_search!="":
353
+ st.divider()
354
+ filtered_recipes = [recipe for recipe in recipes if recipe['name'] == user_search]
355
+ if filtered_recipes:
356
+ show_recipe(filtered_recipes[0])
357
+ else:
358
+ st.write("No recipe found.")