krisha06 commited on
Commit
064f427
·
verified ·
1 Parent(s): 5017b8f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -128
app.py CHANGED
@@ -1,109 +1,32 @@
1
  import streamlit as st
2
  import pandas as pd
3
- import chromadb
4
- from sentence_transformers import SentenceTransformer
5
- from transformers import pipeline
6
- from PIL import Image
7
- from io import BytesIO
8
  import requests
9
- import os
10
- from huggingface_hub import login
11
-
12
 
13
  # --- 1. Load Recipes Dataset ---
14
  @st.cache_data
15
- def load_recipes():
16
- try:
17
- recipes_df = pd.read_csv("recipes.csv")
18
- recipes_df = recipes_df.rename(columns={"recipe_name": "title", "directions": "instructions"})
19
- recipes_df = recipes_df[['title', 'ingredients', 'instructions', 'img_src']]
20
- recipes_df.fillna("", inplace=True)
21
- recipes_df["ingredients"] = recipes_df["ingredients"].str.lower().str.replace(r'[^\w\s]', '', regex=True)
22
- recipes_df["combined_text"] = recipes_df["title"] + " " + recipes_df["ingredients"]
23
- return recipes_df
24
- except Exception as e:
25
- st.error(f"⚠ Error loading recipes: {e}")
26
- return pd.DataFrame()
27
-
28
- recipes_df = load_recipes()
29
-
30
- # --- 2. Load SentenceTransformer Model ---
31
- @st.cache_resource
32
- def load_embedding_model():
33
- return SentenceTransformer("all-MiniLM-L6-v2") # Smaller & optimized model
34
-
35
- embedding_model = load_embedding_model()
36
-
37
- # --- 3. Initialize ChromaDB ---
38
- chroma_client = chromadb.PersistentClient(path="./chroma_db")
39
- collection = chroma_client.get_or_create_collection(name="recipe_collection")
40
-
41
- # --- 4. Generate & Store Embeddings ---
42
- def get_sentence_transformer_embeddings(text):
43
- return embedding_model.encode(text).tolist()
44
 
45
- try:
46
- existing_data = collection.get()
47
- existing_ids = set(existing_data.get("ids", [])) # Use `.get()` for safety
48
- except Exception as e:
49
- st.error(f"⚠ ChromaDB Error: {e}")
50
- existing_ids = set()
51
 
52
- for index, row in recipes_df.iterrows():
53
- recipe_id = str(index)
54
- if recipe_id in existing_ids:
55
- continue
56
- embedding = get_sentence_transformer_embeddings(row["combined_text"])
57
- if embedding:
58
- collection.add(
59
- embeddings=[embedding],
60
- documents=[row["combined_text"]],
61
- ids=[recipe_id],
62
- metadatas=[{"title": row["title"], "ingredients": row["ingredients"], "instructions": row["instructions"], "img_src": row["img_src"]}]
63
- )
64
 
65
- # --- 5. Retrieve Similar Recipes ---
66
- def retrieve_recipes(query, top_k=3):
67
- query_embedding = get_sentence_transformer_embeddings(query)
68
- results = collection.query(query_embeddings=[query_embedding], n_results=top_k)
69
 
70
- if results and results.get("ids"):
71
- recipe_indices = [int(id) for id in results["ids"][0] if id.isdigit()]
72
- return recipes_df.iloc[recipe_indices] if recipe_indices else None
73
- return None
74
-
75
- hf_token = st.secrets["key"]
76
- if hf_token is None:
77
- raise ValueError("Hugging Face token is missing. Add it as a secret in your Space.")
78
- login(token=hf_token)
79
 
80
- # --- 6. Load LLM Model for Generation ---
81
- @st.cache_resource
82
- def load_llm_model():
83
- return pipeline("text-generation", model="mistralai/Mistral-7B-Instruct-v0.3")
84
-
85
- llm_model = load_llm_model()
86
-
87
- # --- 7. Validate Recipe Query ---
88
- def is_recipe_query(query):
89
- # Check if the query includes any food-related words
90
- food_keywords = ["recipe", "cook", "ingredient", "dish", "food", "meal","Prepare","Make"]
91
- return any(keyword in query.lower() for keyword in food_keywords)
92
-
93
- def generate_recipe(query):
94
- related_recipes = retrieve_recipes(query, top_k=2)
95
-
96
- if not related_recipes or related_recipes.empty:
97
- return "I couldn't find a matching recipe, but let me create one for you!"
98
-
99
- base_text = "\n".join([f"- {r['title']}: {r['ingredients']}" for _, r in related_recipes.iterrows()])
100
- # Construct the full prompt for generating a recipe
101
- full_prompt = f"Using these ingredients: {query}, create a unique recipe.\n\nHere are similar recipes:\n{base_text}\n\nNow create a new recipe that uses these ideas."
102
-
103
- response = llm_model(full_prompt, max_length=200, num_return_sequences=1)
104
- return response[0]["generated_text"]
105
-
106
- # --- 8. Display Image Function ---
107
  def display_image(image_url, recipe_name):
108
  try:
109
  if not isinstance(image_url, str) or not image_url.startswith("http"):
@@ -112,36 +35,24 @@ def display_image(image_url, recipe_name):
112
  response.raise_for_status()
113
  image = Image.open(BytesIO(response.content))
114
  st.image(image, caption=recipe_name, use_container_width=True)
115
- except requests.exceptions.RequestException as e:
116
- st.warning(f"Image fetch error: {e}")
117
- placeholder_url = "https://via.placeholder.com/300?text=No+Image"
118
- st.image(placeholder_url, caption=recipe_name, use_container_width=True)
119
-
120
- # --- 9. Streamlit UI ---
121
- st.title("🍽️ AI Recipe Assistant")
122
-
123
- user_query = st.text_input("Enter your recipe search query:", "", key="main_query_input")
124
-
125
- if "retrieved_recipes" not in st.session_state:
126
- st.session_state["retrieved_recipes"] = None
127
-
128
- if st.button("Ask AI"):
129
- if user_query:
130
- if is_recipe_query(user_query): # Check if it's food-related
131
- st.subheader("🤖 AI Response:")
132
- response = generate_recipe(user_query)
133
- st.write(response)
134
-
135
- retrieved_recipes = retrieve_recipes(user_query)
136
- if retrieved_recipes is not None and not retrieved_recipes.empty:
137
- st.session_state["retrieved_recipes"] = retrieved_recipes
138
- st.subheader("🍴 Found Recipes:")
139
- for _, recipe in retrieved_recipes.iterrows():
140
- st.markdown(f"### {recipe['title']}")
141
- st.write(f"**Ingredients:** {recipe['ingredients']}")
142
- st.write(f"**Instructions:** {recipe['instructions']}")
143
- display_image(recipe.get('img_src', ''), recipe['title'])
144
- else:
145
- st.warning("⚠️ No relevant recipes found.")
146
- else:
147
- st.write("I can't answer that. Please ask me about recipes.")
 
1
  import streamlit as st
2
  import pandas as pd
 
 
 
 
 
3
  import requests
4
+ from io import BytesIO
5
+ from PIL import Image
6
+ from transformers import pipeline
7
 
8
  # --- 1. Load Recipes Dataset ---
9
  @st.cache_data
10
+ def load_data():
11
+ return pd.read_csv("recipes.csv")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
+ df = load_data()
 
 
 
 
 
14
 
15
+ # --- 2. Initialize LLM Pipeline ---
16
+ llm = pipeline("text-generation", model="facebook/opt-1.3b")
 
 
 
 
 
 
 
 
 
 
17
 
18
+ # --- 3. Retrieve Recipe Function ---
19
+ def retrieve_recipe(query):
20
+ matching_recipes = df[df['recipe_name'].str.contains(query, case=False, na=False)]
21
+ return matching_recipes if not matching_recipes.empty else None
22
 
23
+ # --- 4. Generate Response for Non-Recipe Queries ---
24
+ def generate_response(query):
25
+ prompt = f"You are an AI assistant that only provides recipe-related responses. If the user asks something unrelated to recipes, politely decline. Query: {query}"
26
+ response = llm(prompt, max_length=100, do_sample=True)[0]['generated_text']
27
+ return response
 
 
 
 
28
 
29
+ # --- 5. Display Image Function ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  def display_image(image_url, recipe_name):
31
  try:
32
  if not isinstance(image_url, str) or not image_url.startswith("http"):
 
35
  response.raise_for_status()
36
  image = Image.open(BytesIO(response.content))
37
  st.image(image, caption=recipe_name, use_container_width=True)
38
+ except requests.exceptions.RequestException:
39
+ st.image("https://via.placeholder.com/300?text=No+Image", caption=recipe_name, use_container_width=True)
40
+
41
+ # --- 6. Streamlit UI ---
42
+ st.title("🍽 Recipe Finder RAG App")
43
+ query = st.text_input("Ask me for a recipe:")
44
+
45
+ if query:
46
+ recipe_result = retrieve_recipe(query)
47
+ if recipe_result is not None:
48
+ for _, row in recipe_result.iterrows():
49
+ st.subheader(row['recipe_name'])
50
+ st.write(f"**Prep Time:** {row['prep_time']} | **Cook Time:** {row['cook_time']} | **Total Time:** {row['total_time']}")
51
+ st.write(f"**Servings:** {row['servings']} | **Yield:** {row['yield']}")
52
+ st.write(f"**Ingredients:** {row['ingredients']}")
53
+ st.write(f"**Directions:** {row['directions']}")
54
+ st.write(f"[View Full Recipe]({row['url']})")
55
+ display_image(row['img_src'], row['recipe_name'])
56
+ else:
57
+ st.warning("⚠ No recipe found! Generating a response...")
58
+ st.write(generate_response(query))