FoodChain / app.py
tonyliu404's picture
Update app.py
7414c03 verified
raw
history blame
4.67 kB
import numpy as np
import pandas as pd # type: ignore
import os
import keras
import tensorflow as tf
from tensorflow.keras.models import load_model
import pymongo
import streamlit as st
from sentence_transformers import SentenceTransformer
from langchain.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain.schema.runnable import RunnablePassthrough
from langchain.schema.output_parser import StrOutputParser
from langchain_core.messages import HumanMessage, SystemMessage
from PIL import Image
import json
st.set_page_config(
page_title="Food Chain",
page_icon="🍴"
)
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
mongo_uri = os.getenv("MONGO_URI_RAG_RECIPE")
@st.cache_resource
def loadEmbedding():
embedding = SentenceTransformer("thenlper/gte-large")
return embedding
embedding = loadEmbedding()
def getEmbedding(text):
if not text.strip():
print("Text was empty")
return []
encoded = embedding.encode(text)
return encoded.tolist()
# Connect to MongoDB
def get_mongo_client(mongo_uri):
try:
client = pymongo.MongoClient(mongo_uri)
print("Connection to MongoDB successful")
return client
except pymongo.errors.ConnectionFailure as e:
print(f"Connection failed: {e}")
return None
if not mongo_uri:
print("MONGO_URI not set in env")
mongo_client = get_mongo_client(mongo_uri)
mongo_db = mongo_client['recipes']
mongo_collection = mongo_db['recipesCollection']
def vector_search(user_query, collection):
query_embedding = getEmbedding(user_query)
if query_embedding is None:
return "Invalid query or embedding gen failed"
vector_search_stage = {
"$vectorSearch": {
"index": "vector_index",
"queryVector": query_embedding,
"path": "embedding",
"numCandidates": 150, # Number of candidate matches to consider
"limit": 4 # Return top 4 matches
}
}
unset_stage = {
"$unset": "embedding" # Exclude the 'embedding' field from the results
}
project_stage = {
"$project": {
"_id": 0, # Exclude the _id field
"name": 1,
"minutes": 1,
"tags": 1,
"n_steps": 1,
"description": 1,
"ingredients": 1,
"n_ingredients": 1,
"formatted_nutrition": 1,
"formatted_steps": 1,
"score": {
"$meta": "vectorSearchScore" # Include the search score
}
}
}
pipeline = [vector_search_stage, unset_stage, project_stage]
results = mongo_collection.aggregate(pipeline)
return list(results)
def mongo_retriever(query):
documents = vector_search(query, mongo_collection)
return documents
template = """
You are an assistant for generating results based on user questions.
Use the provided context to generate a result based on the following JSON format:
{{
"name": "Recipe Name",
"minutes": 0,
"tags": [
"tag1",
"tag2",
"tag3"
],
"n_steps": 0,
"description": "A GENERAL description of the recipe goes here.",
"ingredients": [
"ingredient1",
"ingredient2",
"ingredient3"
],
"n_ingredients": 0,
"formatted_nutrition": [
"Calorie : per serving",
"Total Fat : % daily value",
"Sugar : % daily value",
"Sodium : % daily value",
"Protein : % daily value",
"Saturated Fat : % daily value",
"Total Carbohydrate : % daily value"
],
"formatted_steps": [
"1. Step 1 of the recipe.",
"2. Step 2 of the recipe.",
"3. Step 3 of the recipe."
]
}}
Instructions:
1. Focus on the user's specific request and avoid irrelevant ingredients or approaches.
2. Do not return anything other than the JSON.
3. If the answer is unclear or the context does not fully address the prompt, return []
4. Base the response on simple, healthy, and accessible ingredients and techniques.
5. Rewrite the description in third person
Context: {context}
When choosing a recipe from the context, FOLLOW these instructions:
1. The recipe should be makeable from scratch, using only proper ingredients and not other dishes or pre-made recipes
Question: {question}
"""
custom_rag_prompt = ChatPromptTemplate.from_template(template)
llm = ChatOpenAI(
model_name="gpt-3.5-turbo",
temperature=0.2)
rag_chain = (
{"context": mongo_retriever, "question": RunnablePassthrough()}
| custom_rag_prompt
| llm
| StrOutputParser()
)
def get_response(query):
return rag_chain.invoke(query)
print("HELLO WORLD")
st.title("RESSSSULTS")