krisha06 commited on
Commit
505ab2e
·
verified ·
1 Parent(s): 492836a

Upload 3 files

Browse files
Files changed (3) hide show
  1. Recipe_maker/app.py +149 -0
  2. Recipe_maker/requirements.txt +12 -0
  3. recipes.csv +0 -0
Recipe_maker/app.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import chromadb
4
+ from sentence_transformers import SentenceTransformer
5
+ import requests
6
+ from PIL import Image
7
+ from io import BytesIO
8
+ from transformers import pipeline
9
+
10
+ # --- 1. Setup Hugging Face API for Mistral ---
11
+ huggingface_api_key = st.secrets["HUGGINGFACE_API_KEY"]# Replace with your Hugging Face API key
12
+ model_name = "mistralai/Mistral-7B-Instruct-v0.1"
13
+
14
+ def generate_mistral_response(prompt):
15
+ """Generates text using Mistral from Hugging Face API."""
16
+ api_url = f"https://api-inference.huggingface.co/models/{model_name}"
17
+ headers = {"Authorization": f"Bearer {huggingface_api_key}"}
18
+ payload = {"inputs": prompt}
19
+
20
+ response = requests.post(api_url, headers=headers, json=payload)
21
+ if response.status_code == 200:
22
+ return response.json()[0]["generated_text"]
23
+ else:
24
+ return f"Error: {response.json()}"
25
+
26
+ # Initialize embedding model
27
+ embedding_model = SentenceTransformer('all-mpnet-base-v2')
28
+
29
+ # Initialize ChromaDB
30
+ chroma_client = chromadb.PersistentClient(path="./chroma_db")
31
+ collection = chroma_client.get_or_create_collection(name="recipe_collection")
32
+
33
+ # --- 2. Load Dataset ---
34
+ dataset_path = "recipes.csv"
35
+ try:
36
+ recipes_df = pd.read_csv(dataset_path)
37
+ except FileNotFoundError:
38
+ st.error(f"Error: File not found at {dataset_path}")
39
+ st.stop()
40
+
41
+ # Fix column names (rename 'recipe_name' to 'title')
42
+ if "recipe_name" in recipes_df.columns:
43
+ recipes_df.rename(columns={"recipe_name": "title"}, inplace=True)
44
+
45
+ # Ensure dataset contains required columns
46
+ required_columns = {"title", "ingredients", "img_src"}
47
+ missing_columns = required_columns - set(recipes_df.columns)
48
+ if missing_columns:
49
+ st.error(f"Missing columns in dataset: {missing_columns}")
50
+ st.stop()
51
+
52
+ # Clean dataset
53
+ recipes_df.fillna("", inplace=True)
54
+ recipes_df["ingredients"] = recipes_df["ingredients"].str.lower().str.replace(r'[^\w\s]', '', regex=True)
55
+ recipes_df["combined_text"] = recipes_df["title"] + " " + recipes_df["ingredients"]
56
+
57
+ # --- 3. Generate Embeddings and Store in ChromaDB ---
58
+ def get_sentence_transformer_embeddings(text):
59
+ return embedding_model.encode(text).tolist()
60
+
61
+ # Ensure ChromaDB collection exists
62
+ try:
63
+ existing_data = collection.get()
64
+ existing_ids = set(existing_data["ids"]) if existing_data and "ids" in existing_data else set()
65
+ except Exception as e:
66
+ st.error(f"⚠️ Error fetching ChromaDB data: {e}")
67
+ existing_ids = set()
68
+
69
+ # Add new embeddings only if not already in ChromaDB
70
+ for index, row in recipes_df.iterrows():
71
+ recipe_id = str(index)
72
+ if recipe_id in existing_ids:
73
+ continue
74
+
75
+ embedding = get_sentence_transformer_embeddings(row["combined_text"])
76
+ if embedding:
77
+ collection.add(
78
+ embeddings=[embedding],
79
+ documents=[row["combined_text"]],
80
+ ids=[recipe_id]
81
+ )
82
+
83
+ # --- 4. Retrieval Function ---
84
+ def retrieve_recipes(query, top_k=3):
85
+ """Retrieves most relevant recipes."""
86
+ query_embedding = get_sentence_transformer_embeddings(query)
87
+ results = collection.query(query_embeddings=[query_embedding], n_results=top_k)
88
+
89
+ if results and "documents" in results and results["documents"]:
90
+ recipe_indices = [int(id) for id in results["ids"][0]]
91
+ return recipes_df.iloc[recipe_indices] if recipe_indices else None
92
+ return None
93
+
94
+ # --- 5. Generate AI Recipe using Mistral ---
95
+ def generate_recipe(user_query, retrieved_recipes):
96
+ """Generates a recipe using Mistral API."""
97
+ try:
98
+ relevant_ingredients = set()
99
+ for _, recipe in retrieved_recipes.iterrows():
100
+ relevant_ingredients.update(recipe["ingredients"].split())
101
+
102
+ structured_prompt = (
103
+ f"Create a new recipe using these ingredients: {', '.join(relevant_ingredients)}.\n"
104
+ f"Make sure the recipe matches: {user_query}.\n"
105
+ "- Recipe Name\n- Ingredients\n- Steps\n"
106
+ )
107
+
108
+ response = generate_mistral_response(structured_prompt)
109
+ return response if response else "No response from API."
110
+ except Exception as e:
111
+ return f"Error generating recipe: {e}"
112
+
113
+ # --- 6. Display Image Function ---
114
+ def display_image(image_url, recipe_name):
115
+ """Fetches and displays an image from a URL."""
116
+ try:
117
+ image_response = requests.get(image_url)
118
+ image_response.raise_for_status()
119
+ image = Image.open(BytesIO(image_response.content))
120
+ st.image(image, caption=recipe_name, use_container_width=True)
121
+ except requests.exceptions.RequestException:
122
+ st.warning(f"⚠️ Could not fetch image for {recipe_name}")
123
+
124
+ # --- 7. Streamlit UI ---
125
+ st.title("🍽️ AI Recipe Generator with Mistral")
126
+
127
+ user_query = st.text_input("Enter a dish name or ingredients:", "")
128
+
129
+ if st.button("Find Recipe"):
130
+ if user_query:
131
+ retrieved_recipes = retrieve_recipes(user_query)
132
+
133
+ if retrieved_recipes is not None and not retrieved_recipes.empty:
134
+ st.subheader("🍴 Found Recipes:")
135
+ for _, recipe in retrieved_recipes.iterrows():
136
+ st.markdown(f"### {recipe['title']}")
137
+ st.write(f"**Ingredients:** {recipe['ingredients']}")
138
+
139
+ if "img_src" in recipe and recipe["img_src"].strip():
140
+ display_image(recipe["img_src"], recipe["title"])
141
+ else:
142
+ st.warning("⚠️ No image available")
143
+
144
+ generated_recipe = generate_recipe(user_query, retrieved_recipes)
145
+
146
+ st.subheader("📝 AI-Generated Recipe:")
147
+ st.write(generated_recipe)
148
+ else:
149
+ st.warning("⚠️ No relevant recipes found.")
Recipe_maker/requirements.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ google-generativeai
2
+ pandas
3
+ numpy
4
+ chromadb
5
+ sentence-transformers
6
+ streamlit
7
+ torch
8
+ transformers
9
+ diffusers
10
+ accelerate
11
+ pillow
12
+ requests
recipes.csv ADDED
The diff for this file is too large to render. See raw diff