Spaces:
Sleeping
Sleeping
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) | |