Spaces:
Runtime error
Runtime error
File size: 6,942 Bytes
c43beff 35072d4 c43beff 35072d4 c43beff 35072d4 c43beff 35072d4 c43beff 35072d4 c43beff 35072d4 c43beff 35072d4 c43beff 35072d4 c43beff 35072d4 c43beff 35072d4 c43beff 5747ac1 c43beff 5747ac1 c43beff | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | # app.py
import os
from dotenv import load_dotenv
from google import genai
import gradio as gr
# Load environment variables (local .env or HF Secrets)
load_dotenv()
# Initialize Gemini client (will read GEMINI_API_KEY from environment)
client = genai.Client()
MODEL = "gemini-2.5-flash" # quickstart example uses gemini-2.5-flash; change to gemini-2.5-flash-pro if you have access
# --- Utilities ---
def calculate_calorie_requirements(age, gender, weight, height, fitness_goal):
try:
age = float(age); weight = float(weight); height = float(height)
except Exception:
return 0
if gender == "Male":
bmr = 10 * weight + 6.25 * height - 5 * age + 5
else:
bmr = 10 * weight + 6.25 * height - 5 * age - 161
if fitness_goal == "Weight Loss":
return int(bmr * 1.2)
if fitness_goal == "Weight Gain":
return int(bmr * 1.5)
return int(bmr * 1.375)
AYURVEDA_PROMPT = """
You are an expert in modern medicine and Ayurveda. Create a concise personalized weekly diet & exercise plan for {name}, a {age}-year-old {gender} with BMI {bmi} ({health_status}).
Fitness Goal: {fitness_goal}
Daily Calories: {daily_calories} kcal
Diet Preference: {dietary_preference}
Food Allergies: {food_allergies}
Local Cuisine: {local_cuisine}
Month: {month}
Return short bullets for each weekday (Mon..Sun).
"""
REGULAR_PROMPT = """
You are a health expert. Create a concise personalized weekly diet & exercise plan for {name}, a {age}-year-old {gender} with BMI {bmi} ({health_status}).
Fitness Goal: {fitness_goal}
Daily Calories: {daily_calories} kcal
Diet Preference: {dietary_preference}
Food Allergies: {food_allergies}
Local Cuisine: {local_cuisine}
Month: {month}
Return short bullets for each weekday (Mon..Sun).
"""
def call_gemini(prompt_text, model_name=MODEL):
"""
Calls client.models.generate_content exactly as in the official quickstart:
client.models.generate_content(model=..., contents=...)
Returns the best available text representation (response.text or fallbacks).
"""
try:
# Per quickstart: use `contents=` (can be a string or structured contents)
response = client.models.generate_content(model=model_name, contents=prompt_text)
except Exception as e:
return f"Error calling Gemini API: {e}"
# Preferred accessor per docs/examples
if hasattr(response, "text") and response.text:
return response.text
# Fallbacks for various SDK response shapes:
# - candidates -> content -> parts -> text
try:
cand = getattr(response, "candidates", None)
if cand:
first = cand[0]
# dict-like candidate with nested content->parts
if isinstance(first, dict):
content = first.get("content") or {}
parts = content.get("parts") or []
if parts:
texts = []
for p in parts:
if isinstance(p, dict) and p.get("text"):
texts.append(p.get("text"))
elif isinstance(p, str):
texts.append(p)
if texts:
return "\n".join(texts)
# if candidate object has .content.parts style
try:
parts = first.get("content", {}).get("parts", [])
except Exception:
parts = []
if parts:
out = []
for p in parts:
t = p.get("text") if isinstance(p, dict) else str(p)
out.append(t)
return "\n".join(out)
except Exception:
pass
# Last resort: try response.output or stringified response
try:
if hasattr(response, "output"):
return str(response.output)
except Exception:
pass
return str(response)
def generate_plan(name, age, weight, height, gender, fitness_goal, dietary_preference,
food_allergies, local_cuisine, month, include_ayurveda):
# validate numeric values
try:
age_f = float(age); weight_f = float(weight); height_f = float(height)
except Exception:
return "Please enter valid numeric values for age, weight, and height."
bmi = round(weight_f / (height_f / 100) ** 2, 2)
health_status = "Underweight" if bmi < 18.5 else "Normal weight" if bmi <= 24.9 else "Overweight"
daily_calories = calculate_calorie_requirements(age_f, gender, weight_f, height_f, fitness_goal)
metrics = {
"name": name or "User",
"age": int(age_f),
"gender": gender,
"bmi": bmi,
"health_status": health_status,
"fitness_goal": fitness_goal,
"dietary_preference": dietary_preference,
"food_allergies": food_allergies or "None",
"daily_calories": daily_calories,
"local_cuisine": local_cuisine or "Local",
"month": month or ""
}
prompt_template = AYURVEDA_PROMPT if include_ayurveda else REGULAR_PROMPT
prompt = prompt_template.format(**metrics)
text = call_gemini(prompt, model_name=MODEL)
header = f"BMI: {bmi} ({health_status})\nEstimated calories/day: {daily_calories} kcal\n\n"
return header + text
# --- Gradio UI ---
with gr.Blocks(title="AI Health Advisor") as demo:
gr.Markdown("# 🩺 AI-Based Personalized Weekly Diet & Exercise Planner (Gemini quickstart style)")
with gr.Row():
with gr.Column():
name_in = gr.Textbox(label="Name")
age_in = gr.Number(label="Age", value=25)
weight_in = gr.Number(label="Weight (kg)", value=70)
height_in = gr.Number(label="Height (cm)", value=170)
gender_in = gr.Dropdown(label="Gender", choices=["Male", "Female", "Other"], value="Male")
goal_in = gr.Dropdown(label="Fitness Goal", choices=["Weight Loss", "Weight Gain", "Maintenance"], value="Maintenance")
diet_in = gr.Dropdown(label="Diet Preference", choices=["Vegetarian", "Vegan", "Keto", "Halal", "None"], value="None")
allergy_in = gr.Textbox(label="Food Allergies")
cuisine_in = gr.Textbox(label="Local Cuisine")
month_in = gr.Dropdown(label="Month", choices=[
"January","February","March","April","May","June","July","August","September","October","November","December"
], value="October")
ayurveda_in = gr.Checkbox(label="Include Ayurvedic Insights", value=True)
btn = gr.Button("Generate Plan")
with gr.Column():
output = gr.Textbox(label="Generated Plan", lines=25)
btn.click(
generate_plan,
inputs=[name_in, age_in, weight_in, height_in, gender_in, goal_in, diet_in, allergy_in, cuisine_in, month_in, ayurveda_in],
outputs=output
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", share=False)
|