Hammad712 commited on
Commit
b618274
·
verified ·
1 Parent(s): fe1de34

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -272
app.py DELETED
@@ -1,272 +0,0 @@
1
- from fastapi import FastAPI, HTTPException
2
- from pydantic import BaseModel
3
- from pymongo import MongoClient
4
- from urllib.parse import quote_plus
5
- import uuid
6
- from typing import List, Optional
7
- import json
8
- from fastapi import FastAPI, File, UploadFile, HTTPException
9
- from fastapi.responses import HTMLResponse
10
- import os
11
- import base64
12
- from groq import Groq
13
- import faiss
14
- import pickle
15
- import torch
16
- from transformers import CLIPProcessor, CLIPModel
17
- from PIL import Image
18
-
19
- # Load the FAISS index
20
- index = faiss.read_index("knowledge_base.faiss")
21
-
22
- # Load the titles metadata
23
- with open("titles.pkl", "rb") as f:
24
- titles = pickle.load(f)
25
-
26
- # Load CLIP model and processor on CPU
27
- model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32").to("cpu")
28
- processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
29
-
30
- # Initialize Groq client
31
- client = Groq(api_key='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')
32
-
33
- # MongoDB connection setup
34
- def get_mongo_client():
35
- password = quote_plus("momimaad@123") # Change this to your MongoDB password
36
- mongo_uri = f"mongodb+srv://hammad:{password}@cluster0.2a9yu.mongodb.net/"
37
- return MongoClient(mongo_uri)
38
-
39
- db_client = get_mongo_client()
40
- db = db_client["recipe"]
41
- user_collection = db["user_info"]
42
-
43
- # Pydantic models for user data
44
- class User(BaseModel):
45
- first_name: str
46
- last_name: str
47
- email: str
48
- password: str
49
-
50
- class UserData(BaseModel):
51
- email: str
52
- password: str
53
-
54
- class UserToken(BaseModel):
55
- token: str
56
-
57
- class RecipeData(BaseModel):
58
- name: str
59
-
60
- class AltrecipeData(BaseModel):
61
- recipe_name: str
62
- dietary_restrictions: str
63
- allergies: List
64
-
65
- class Ingredient(BaseModel):
66
- name: str
67
- quantity: str
68
-
69
-
70
- class Recipe(BaseModel):
71
- recipe_name: str
72
- ingredients: List[Ingredient]
73
- directions: List[str]
74
-
75
-
76
- class get_recipe_name(BaseModel):
77
- recipe_name: List[str]
78
- ingredients: List[List[str]]
79
-
80
- # Data model for LLM to generate
81
- class Alternative_Ingredient(BaseModel):
82
- name: str
83
- quantity: str
84
-
85
- class Alternative_Recipe(BaseModel):
86
- recipe_name: str
87
- alternative_ingredients: List[Alternative_Ingredient]
88
- alternative_directions: List[str]
89
-
90
- # Function for finding the most similar image
91
- def find_similar_image(image_path, threshold=30.0):
92
- # Load and preprocess the input image
93
- image = Image.open(image_path).convert("RGB")
94
- inputs = processor(images=image, return_tensors="pt")
95
-
96
- # Generate embedding for the input image on CPU
97
- with torch.no_grad():
98
- image_features = model.get_image_features(**inputs).numpy() # No need for .cpu()
99
-
100
- # Perform similarity search in FAISS
101
- distances, indices = index.search(image_features, k=1) # Search for the most similar embedding
102
-
103
- # Check if the closest match meets the threshold
104
- if distances[0][0] < threshold:
105
- return titles[indices[0][0]]
106
- else:
107
- return "Not Found"
108
- def get_recipe(recipe_name: str) -> Recipe:
109
- chat_completion = client.chat.completions.create(
110
- messages=[
111
- {
112
- "role": "system",
113
- "content": f"""Your are an expert agent to generate a recipes with proper and corrected ingredients and direction. Your directions should be concise and to the point and dont explain any irrelevant text.
114
- You are a recipe database that outputs recipes in JSON.\n
115
- The JSON object must use the schema: {json.dumps(Recipe.model_json_schema(), indent=2)}""",
116
- },
117
- {
118
- "role": "user",
119
- "content": f"Fetch a recipe for {recipe_name}",
120
- },
121
- ],
122
- model="llama-3.2-90b-text-preview",
123
- temperature=0,
124
- # Streaming is not supported in JSON mode
125
- stream=False,
126
- # Enable JSON mode by setting the response format
127
- response_format={"type": "json_object"},
128
- )
129
- return Recipe.model_validate_json(chat_completion.choices[0].message.content)
130
-
131
-
132
- def Suggest_ingredient_alternatives(recipe_name: str, dietary_restrictions: str, allergies: List) -> Alternative_Recipe:
133
- chat_completion = client.chat.completions.create(
134
- messages=[
135
- {
136
- "role": "system",
137
- "content": f"""
138
- You are an expert agent to suggest alternatives for specific allergies ingredients for the provided recipe {recipe_name}.
139
-
140
- Please take the following into account:
141
- - If the user has dietary restrictions, suggest substitutes that align with their needs (e.g., vegan, gluten-free, etc.) in alternative_directions and your alternative_directions should be concise and to the point.
142
- -In ingredient you will recommend the safe ingredient for avoid any allergy and dietary restriction.
143
- - Consider the following allergies {allergies} and recommend the safe ingredient to avoid this allergies.
144
-
145
- recipe_name: {recipe_name}
146
- Dietary Restrictions: {dietary_restrictions}
147
- Allergies: {', '.join(allergies)}
148
-
149
- You are a recipe database that outputs alternative recipes to avoid allergy and dietary_restrictions in JSON.\n
150
- The JSON object must use the schema: {json.dumps(Alternative_Recipe.model_json_schema(), indent=2)}""",
151
- },
152
- {
153
- "role": "user",
154
- "content": f"""Fetch a alternative recipe for recipe_name: {recipe_name}
155
- Dietary Restrictions: {dietary_restrictions}
156
- Allergies: {', '.join(allergies)}""",
157
- },
158
- ],
159
- model="llama-3.2-90b-text-preview",
160
- temperature=0,
161
- # Streaming is not supported in JSON mode
162
- stream=False,
163
- # Enable JSON mode by setting the response format
164
- response_format={"type": "json_object"},
165
- )
166
- return Alternative_Recipe.model_validate_json(chat_completion.choices[0].message.content)
167
-
168
- app = FastAPI()
169
-
170
- @app.post("/get_recipe/{token}")
171
- async def get_recipe_response(token: str, recipe_user: RecipeData):
172
- user = user_collection.find_one({"token": token})
173
- if not user:
174
- raise HTTPException(status_code=401, detail="Invalid token")
175
-
176
- # Find user by email
177
- recipe_name = recipe_user.name
178
- response = get_recipe(recipe_name)
179
- return {
180
- "Response": response
181
- }
182
-
183
- @app.post("/get_recipe_alternative/{token}")
184
- async def get_alternative_recipe_response(token: str, altrecipe_user: AltrecipeData):
185
- user = user_collection.find_one({"token": token})
186
- if not user:
187
- raise HTTPException(status_code=401, detail="Invalid token")
188
-
189
- response = Suggest_ingredient_alternatives(altrecipe_user.recipe_name, altrecipe_user.dietary_restrictions, altrecipe_user.allergies)
190
- return {
191
- "Response": response
192
- }
193
-
194
-
195
- # Directory to save uploaded images
196
- UPLOAD_DIR = "uploads"
197
-
198
- # Ensure the upload directory exists
199
- os.makedirs(UPLOAD_DIR, exist_ok=True)
200
-
201
-
202
- # Endpoint to upload an image
203
- @app.post("/upload-image/{token}")
204
- async def upload_image(token: str, file: UploadFile = File(...)):
205
- user = user_collection.find_one({"token": token})
206
- if not user:
207
- raise HTTPException(status_code=401, detail="Invalid token")
208
-
209
- # Validate the file type
210
- if not file.filename.lower().endswith(('.png', '.jpg', '.jpeg')):
211
- raise HTTPException(status_code=400, detail="Invalid file type. Only PNG, JPG, and JPEG are allowed.")
212
-
213
- # Create a file path for saving the uploaded file
214
- file_path = os.path.join(UPLOAD_DIR, file.filename)
215
-
216
- # Save the file
217
- with open(file_path, "wb") as buffer:
218
- buffer.write(await file.read())
219
-
220
- result = find_similar_image(file_path, threshold=30.0)
221
-
222
- return {
223
- "Response": result
224
- }
225
-
226
-
227
- # Endpoint to register a new user
228
- @app.post("/register")
229
- async def register_user(user: User):
230
- # Check if user already exists
231
- existing_user = user_collection.find_one({"email": user.email})
232
- if existing_user:
233
- raise HTTPException(status_code=400, detail="Email already registered")
234
-
235
- # Create user data
236
- user_data = {
237
- "first_name": user.first_name,
238
- "last_name": user.last_name,
239
- "email": user.email,
240
- "password": user.password, # Store plaintext password (not recommended in production)
241
- }
242
-
243
- # Insert the user data into the user_info collection
244
- result = user_collection.insert_one(user_data)
245
- return {"msg": "User registered successfully", "user_id": str(result.inserted_id)}
246
-
247
- # Endpoint to check user credentials and generate a token
248
- @app.post("/get_token")
249
- async def check_credentials(user: UserData):
250
- # Find user by email
251
- existing_user = user_collection.find_one({"email": user.email})
252
-
253
- # Check if user exists and password matches
254
- if not existing_user or existing_user["password"] != user.password:
255
- raise HTTPException(status_code=401, detail="Invalid email or password")
256
-
257
- # Generate a UUID token
258
- token = str(uuid.uuid4())
259
-
260
- # Update the user document with the token
261
- user_collection.update_one({"email": user.email}, {"$set": {"token": token}})
262
-
263
- return {
264
- "first_name": existing_user["first_name"],
265
- "last_name": existing_user["last_name"],
266
- "token": token,
267
- }
268
-
269
-
270
- @app.get("/")
271
- async def root():
272
- return {"message": "API is up and running!"}