Nutricious / app.py
Santhosh54321's picture
Update app.py
7d1bfcb verified
raw
history blame
7.57 kB
import streamlit as st
import base64
from huggingface_hub import InferenceClient
import os
import requests
# Initialize Hugging Face Inference client using tokens from environment variables
client = InferenceClient(api_key=os.getenv("HF_API_TOKEN_DISH"))
client1 = InferenceClient(api_key=os.getenv("HF_API_TOKEN_DIET"))
groq_api_key = os.getenv("API_Groq")
# 1. Function to identify dish from image
def identify_dish(image_bytes):
encoded_image = base64.b64encode(image_bytes).decode("utf-8")
dish_name = ""
for message in client.chat_completion(
model="meta-llama/Llama-3.2-11B-Vision-Instruct",
messages=[
{
"role": "You are a highly specialized food identification AI...",
"content": [
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{encoded_image}" }},
{"type": "text", "text": "Identify the dishes in the image and return only the names of the dishes."},
],
}
],
max_tokens=70,
stream=True,
):
if message.choices[0].delta.content:
dish_name += message.choices[0].delta.content
return dish_name.strip()
# 2. Function to calculate daily caloric needs
def calculate_metrics(age, gender, height_cm, weight_kg, weight_goal, activity_level, time_frame_months):
bmi = weight_kg / ((height_cm / 100) ** 2)
if gender == "male":
bmr = 10 * weight_kg + 6.25 * height_cm - 5 * age + 5
else:
bmr = 10 * weight_kg + 6.25 * height_cm - 5 * age - 161
activity_multipliers = {
"sedentary": 1.2,
"light": 1.375,
"moderate": 1.55,
"active": 1.725,
"very active": 1.9
}
tdee = bmr * activity_multipliers[activity_level]
if gender == "male":
ibw = 50 + (0.91 * (height_cm - 152.4))
else:
ibw = 45.5 + (0.91 * (height_cm - 152.4))
if weight_goal == "loss":
daily_caloric_needs = tdee - 500
elif weight_goal == "gain":
daily_caloric_needs = tdee + 500
else:
daily_caloric_needs = tdee
protein_calories = daily_caloric_needs * 0.2
fat_calories = daily_caloric_needs * 0.25
carbohydrate_calories = daily_caloric_needs * 0.55
return {
"BMI": bmi,
"BMR": bmr,
"TDEE": tdee,
"IBW": ibw,
"Daily Caloric Needs": daily_caloric_needs,
"Protein Calories": protein_calories,
"Fat Calories": fat_calories,
"Carbohydrate Calories": carbohydrate_calories
}
# 3. Function to generate diet plan
def generate_diet_plan(dish_name, calorie_intake_per_day, goal):
user_input = f"""
You are a certified Dietitian with 20 years of experience. Based on the following input, create an Indian diet plan...
Input:
- Dish Name: {dish_name}
- Caloric Intake per Day: {calorie_intake_per_day} calories
- Goal: {goal}
"""
response = client1.chat_completion(
model="meta-llama/Meta-Llama-3-8B-Instruct",
messages=[{"role": "You are a certified Dietitian with 20 years of Experience", "content": user_input}],
max_tokens=500
)
return response.choices[0].message.content
# 4. Function to generate a recipe using Groq API
def generate_recipe(recipe_name):
url = "https://api.groq.com/openai/v1/chat/completions"
headers = {
"Authorization": f"Bearer {groq_api_key}",
"Content-Type": "application/json"
}
data = {
"model": "gpt-3.5-turbo",
"messages": [
{"role": "system", "content": "You are a skilled chef."},
{"role": "user", "content": f"Create a detailed recipe for {recipe_name}"}
]
}
response = requests.post(url, headers=headers, json=data)
if response.status_code == 200:
result = response.json()
generated_recipe = result['choices'][0]['message']['content']
return generated_recipe
else:
return f"Error: {response.status_code}, {response.text}"
# Streamlit App Title
st.title("AI Diet Planner")
# Sidebar for user input
st.sidebar.title("User Input")
image_file = st.sidebar.file_uploader("Upload an image of the dish", type=["jpeg", "png"])
age = st.sidebar.number_input("Enter your age", min_value=1)
gender = st.sidebar.selectbox("Select your gender", ["male", "female"])
height_cm = st.sidebar.number_input("Enter your height (cm)", min_value=1.0)
weight_kg = st.sidebar.number_input("Enter your weight (kg)", min_value=1.0)
weight_goal = st.sidebar.selectbox("Weight goal", ["loss", "gain", "maintain"])
activity_level = st.sidebar.selectbox("Activity level", ["sedentary", "light", "moderate", "active", "very active"])
time_frame = st.sidebar.number_input("Time frame to achieve goal (months)", min_value=1)
# Submit button
submit = st.sidebar.button("Submit")
# Process the image and calculate metrics upon submission
if submit:
if image_file:
st.write("### Results")
image_bytes = image_file.read()
# Step 1: Identify the dish
dish_name = identify_dish(image_bytes)
st.markdown("<hr>", unsafe_allow_html=True)
st.write("#### Dish Name Identified:")
st.markdown(f"<div style='background-color: #d4edda; color: #155724; padding: 10px; border-radius: 10px;'>{dish_name}</div>", unsafe_allow_html=True)
# Step 2: Perform Calculations
metrics = calculate_metrics(age, gender, height_cm, weight_kg, weight_goal, activity_level, time_frame)
st.markdown("<hr>", unsafe_allow_html=True)
st.write("#### Metrics Calculated:")
st.markdown(f"""
<div style='background-color: #f8d7da; color: #721c24; padding: 10px; border-radius: 10px;'>
<p><b>Your BMI:</b> {metrics['BMI']:.2f}</p>
<p><b>Your BMR:</b> {metrics['BMR']:.2f} calories</p>
<p><b>Your TDEE:</b> {metrics['TDEE']:.2f} calories</p>
<p><b>Ideal Body Weight (IBW):</b> {metrics['IBW']:.2f} kg</p>
<p><b>Daily Caloric Needs:</b> {metrics['Daily Caloric Needs']:.2f} calories</p>
</div>
""", unsafe_allow_html=True)
# Step 3: Generate diet plan
diet_plan = generate_diet_plan(dish_name, metrics["Daily Caloric Needs"], weight_goal)
st.markdown("<hr>", unsafe_allow_html=True)
st.write("#### Diet Plan Based on Dish & Goal:")
st.markdown(f"<div style='background-color: #d1ecf1; color: #0c5460; padding: 10px; border-radius: 10px;'>{diet_plan}</div>", unsafe_allow_html=True)
# Step 4: Ask for recipe generation
st.markdown("<hr>", unsafe_allow_html=True)
recipe_option = st.radio("Would you like a recipe for a dish?", ["No", "Yes"])
if recipe_option == "Yes":
recipe_name = st.text_input("Enter the dish name for the recipe:")
if st.button("Generate Recipe"):
recipe = generate_recipe(recipe_name)
st.write("### Generated Recipe:")
st.markdown(f"<div style='background-color: #fff3cd; color: #856404; padding: 10px; border-radius: 10px;'>{recipe}</div>", unsafe_allow_html=True)
else:
st.error("Please upload a valid image in JPEG or PNG format.")
# CSS styling
st.markdown("""
<style>
.stButton button { background-color: #4CAF50; color: white; }
.stContainer { border: 1px solid #ddd; padding: 20px; margin-bottom: 20px; }
hr { border: 1px solid #e9ecef; margin: 20px 0; }
</style>
""", unsafe_allow_html=True)