import os import random import uuid import gradio as gr from pydub import AudioSegment import whisper import requests # === Load Whisper Model === try: whisper_model = whisper.load_model("tiny") # Fast transcription except AttributeError: raise ImportError("Failed to load Whisper model. Install from OpenAI GitHub: pip install -U git+https://github.com/openai/whisper.git") # === USDA API Configuration (Demo Key) === USDA_API_KEY = "DEMO_KEY" # Replace with registered key USDA_API_URL = "https://api.nal.usda.gov/fdc/v1/foods/search" usda_cache = {} # In-memory cache for speed def fetch_usda_food_data(query): if query in usda_cache: return usda_cache[query] params = {"api_key": USDA_API_KEY, "query": query, "dataType": ["Branded", "SR Legacy"]} try: response = requests.get(USDA_API_URL, params=params, timeout=2) response.raise_for_status() data = response.json() result = data.get("foods", [])[0].get("description", query) if data.get("foods") else query usda_cache[query] = result return result except Exception: return query # === Supported Languages === lang_map = {"English": "en"} # === Preloaded Food Database === local_foods = { "vegetables": ["Carrot", "Tomato", "Spinach"], "fruits": ["Apple", "Banana"], "grains": ["Rice", "Wheat"], "proteins": ["Lentils", "Tofu"], "dairy": ["Curd"] } # === Meal Templates === meal_templates = { "breakfast": ["{grain} porridge with {fruit}", "{grain} upma"], "lunch": ["{protein} curry with {grain}", "{grain} khichdi"], "dinner": ["{vegetable} soup with {grain}"] } # === Generate Test Audio Files (With Error Handling) === def generate_test_audio(): required_files = ["test_health_conditions.wav", "test_dietary_preferences.wav", "test_allergies.wav"] if all(os.path.exists(f) for f in required_files): print("Using existing test audio files.") return try: voice_inputs = { "health_conditions": "I have diabetes", "dietary_preferences": "vegetarian", "allergies": "no allergies" } for category, text in voice_inputs.items(): filename = f"test_{category}.mp3" wav_filename = f"test_{category}.wav" if not os.path.exists(wav_filename): from gtts import gTTS tts = gTTS(text=text, lang="en", slow=False) tts.save(filename) audio = AudioSegment.from_mp3(filename) audio.export(wav_filename, format="wav") os.remove(filename) print("Test audio files generated or verified.") except Exception as e: print(f"Failed to generate audio files: {e}. Using existing files or manual input required.") if not any(os.path.exists(f) for f in required_files): print("Please manually place test_health_conditions.wav, test_dietary_preferences.wav, and test_allergies.wav in the app directory.") generate_test_audio() # Run once with error handling # === CSS for Clean UI === custom_css = """ .gradio-container { background: linear-gradient(rgba(129, 199, 132, 0.4), rgba(46, 139, 87, 0.2)); min-height: 100vh; padding: 20px; font-family: 'Arial', sans-serif; } .app-header { text-align: center; padding: 15px; background: rgba(255, 255, 255, 0.95); border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } .input-section { background: rgba(255, 255, 255, 0.9); padding: 15px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); display: grid; gap: 10px; } .output-section { background: rgba(255, 255, 255, 0.95); padding: 15px; border-radius: 10px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); display: grid; gap: 10px; } .output-card { background: #f9f9f9; padding: 10px; border-radius: 5px; border-left: 4px solid #4CAF50; } button { background: linear-gradient(135deg, #4CAF50, #45a049); color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; } button:hover { background: linear-gradient(135deg, #45a049, #3d8b40); } label { font-weight: 600; color: #2E8B57; } h2 { color: #2E8B57; font-size: 1.5em; margin: 0 0 10px; } h3 { color: #4CAF50; font-size: 1.1em; margin: 10px 0 5px; } p { margin: 5px 0; line-height: 1.5; color: #555; } """ # === Output Template === def get_output_template() -> str: return """
Age: {age} yrs | Gender: {gender}
Weight: {weight} kg | Height: {height} cm
Occupation: {occupation}
Activity Level: {activity_level}
{health_conditions}
{dietary_preferences}
{allergies}
🥣 Breakfast: {breakfast}
🍛 Lunch: {lunch}
🥗 Dinner: {dinner}