Spaces:
Sleeping
Sleeping
File size: 4,108 Bytes
f0c74c4 | 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 | import os
import logging
import json
from fastapi import APIRouter, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
import google.generativeai as genai
from dotenv import load_dotenv
import re # Extract JSON safely
# Load environment variables
load_dotenv()
# Retrieve API Key
API_KEY = os.getenv("GEMINI_API_KEY")
if not API_KEY:
raise ValueError("❌ Missing GEMINI_API_KEY. Please set it in the .env file.")
# Configure Gemini AI
genai.configure(api_key=API_KEY)
model = genai.GenerativeModel("gemini-2.0-flash")
# Initialize API Router
router = APIRouter()
# Configure Logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
# Define Request Model
class PlayerProfile(BaseModel):
sport: str
position: str
age: int
weight: float
height: float
goal: str
# Function to extract JSON from AI response
def extract_json(response_text: str) -> dict:
"""Extract JSON from the AI response safely."""
try:
json_match = re.search(r"\{.*\}", response_text, re.DOTALL)
if json_match:
json_str = json_match.group(0)
return json.loads(json_str)
else:
raise ValueError("No valid JSON found in AI response.")
except Exception as e:
logging.error(f"⚠️ Error parsing AI JSON response: {e}")
return {"error": "AI response did not return valid JSON."}
# AI-based Diet Plan Generation
def generate_diet_plan(player_profile: PlayerProfile) -> dict:
try:
prompt = f"""
Suggest a **daily meal plan** for an athlete based on the following details:
- **Sport**: {player_profile.sport}
- **Position**: {player_profile.position}
- **Age**: {player_profile.age}
- **Weight**: {player_profile.weight} kg
- **Height**: {player_profile.height} cm
- **Training Goal**: {player_profile.goal}
Provide a structured meal plan including:
- **Breakfast**
- **Lunch**
- **Dinner**
- **Snacks**
- **Macronutrient Breakdown (Protein, Carbs, Fats)**
Return the response in this **JSON format**:
```json
{{
"diet_plan": {{
"overview": {{
"sport": "{player_profile.sport}",
"position": "{player_profile.position}",
"age": {player_profile.age},
"weight": {player_profile.weight},
"height": {player_profile.height},
"goal": "{player_profile.goal}"
}},
"meal_plan": {{
"breakfast": ["Example breakfast item 1", "Example breakfast item 2"],
"lunch": ["Example lunch item 1", "Example lunch item 2"],
"snacks": ["Example snack item 1", "Example snack item 2"],
"dinner": ["Example dinner item 1", "Example dinner item 2"]
}},
"macronutrients": {{
"protein": "Example grams of protein",
"carbs": "Example grams of carbs",
"fats": "Example grams of fats"
}}
}}
}}
```
Return only **valid JSON**.
"""
response = model.generate_content(prompt)
if not response or not response.text:
raise ValueError("AI response is empty.")
response_text = response.text.strip()
return extract_json(response_text) # Extract only valid JSON
except Exception as e:
logging.error(f"❌ Error in AI response: {str(e)}")
return {"error": "Failed to generate diet plan."}
# Diet Plan Endpoint
@router.post("/generate_diet/")
async def generate_diet(player_profile: PlayerProfile):
try:
logging.info(f"📩 Received Diet Plan Request: {player_profile}")
diet_plan = generate_diet_plan(player_profile)
return JSONResponse(content=diet_plan, status_code=200)
except Exception as e:
logging.error(f"❌ Error Processing Request: {str(e)}")
raise HTTPException(status_code=500, detail="Internal Server Error")
|