import gradio as gr import base64 from groq import Groq from PIL import Image import io import os # Initialize Groq client client = Groq(api_key=os.getenv("GROQ_API_KEY")) # Convert image → base64 def encode_image(image): buffered = io.BytesIO() image.save(buffered, format="JPEG") return base64.b64encode(buffered.getvalue()).decode() # 🔍 STEP 1: Detect ingredients def analyze_ingredients(image): if image is None: return "Please upload an image." base64_image = encode_image(image) try: completion = client.chat.completions.create( model="meta-llama/llama-4-scout-17b-16e-instruct", messages=[ { "role": "user", "content": [ { "type": "text", "text": """ Analyze this image carefully. If the image contains food: → List all ingredients clearly (comma separated). If the image does NOT contain food: → Respond ONLY with: NO_FOOD_DETECTED """ }, { "type": "image_url", "image_url": { "url": f"data:image/jpeg;base64,{base64_image}" } } ], } ], temperature=0.3, ) result = completion.choices[0].message.content.strip() return result except Exception as e: return f"Error: {str(e)}" # 🍲 STEP 2: Generate recipe def generate_recipe(ingredients_text): if not ingredients_text: return "No ingredients detected." # 🚨 HARD BLOCK for non-food if "NO_FOOD_DETECTED" in ingredients_text: return "❌ No food detected in the image. Please upload a valid food image." # Extra safety filter bad_keywords = ["diagram", "cnn", "architecture", "network", "chart"] if any(word in ingredients_text.lower() for word in bad_keywords): return "❌ Invalid input. This does not look like food ingredients." try: completion = client.chat.completions.create( model="llama-3.1-8b-instant", messages=[ { "role": "user", "content": f""" You are a strict cooking assistant. Only generate a recipe if the input contains real food ingredients. Ingredients: {ingredients_text} If this is NOT food → reply exactly: INVALID_FOOD_INPUT Otherwise provide: - Dish name - Ingredients - Step-by-step instructions """ } ], temperature=0.7, ) result = completion.choices[0].message.content.strip() # 🚨 Final safety check if "INVALID_FOOD_INPUT" in result: return "❌ Could not generate recipe. Invalid food input." return result except Exception as e: return f"Error: {str(e)}" # 🎨 UI with gr.Blocks(title="AI Cooking Assistant") as app: gr.Markdown("# 🍳 AI Cooking Assistant") gr.Markdown("Upload food image → Detect ingredients → Generate recipe") image_input = gr.Image(type="pil", label="Upload Ingredients Image") detect_btn = gr.Button("🔍 Detect Ingredients") ingredients_output = gr.Textbox(label="Detected Ingredients") recipe_btn = gr.Button("🍲 Generate Recipe") recipe_output = gr.Textbox(label="Recipe", lines=12) detect_btn.click(analyze_ingredients, inputs=image_input, outputs=ingredients_output) recipe_btn.click(generate_recipe, inputs=ingredients_output, outputs=recipe_output) app.launch()