import gradio as gr import requests import os from openai import OpenAI # Initialize Groq LLM client client = OpenAI( api_key=os.getenv("GROQ_API_KEY"), base_url="https://api.groq.com/openai/v1", ) # Store search results product_cache = [] # Step 1: Search products def search_products(product_name): global product_cache url = f"https://world.openfoodfacts.org/cgi/search.pl?search_terms={product_name}&search_simple=1&action=process&json=1&page_size=10" response = requests.get(url) if response.status_code != 200: return [], gr.update(visible=False), gr.update(visible=False), gr.update(choices=[], visible=False) data = response.json() products = data.get("products", []) product_cache = [] dropdown_choices = [] display_rows = [] for i, p in enumerate(products): if not p.get("product_name"): continue product_cache.append(p) product_display = f"{p.get('product_name', 'N/A')} | {p.get('packaging', 'N/A')} | {p.get('categories', 'N/A')}" dropdown_choices.append(product_display) display_rows.append([ p.get("product_name", "N/A"), p.get("packaging", "N/A"), p.get("categories", "N/A"), p.get("code", "") ]) return display_rows, gr.update(visible=True), gr.update(visible=True), gr.update(choices=dropdown_choices, visible=True) # Step 2: Score product def score_product(p): packaging = (p.get("packaging") or "").lower() categories = (p.get("categories") or "").lower() ingredients = (p.get("ingredients_text") or "").lower() score = 50 # base score # Packaging impact if "plastic" in packaging: score -= 25 elif "glass" in packaging: score += 10 elif "paper" in packaging or "cardboard" in packaging: score += 5 elif "recyclable" in packaging: score += 8 elif "biodegradable" in packaging or "compostable" in packaging: score += 12 # Category-based adjustments if "organic" in categories: score += 10 if "local" in categories: score += 5 if "meat" in categories or "processed food" in categories: score -= 15 if "vegan" in categories: score += 10 if "snacks" in categories or "ready meals" in categories: score -= 10 # Ingredient clues if "palm oil" in ingredients: score -= 10 if "organic" in ingredients: score += 5 if "artificial flavor" in ingredients or "preservative" in ingredients: score -= 5 # Normalize score return max(0, min(score, 100)) # Step 3: Groq explanation def generate_explanation(p, score): prompt = f""" You are an environmental sustainability expert. Product: - Name: {p.get('product_name')} - Packaging: {p.get('packaging')} - Categories: {p.get('categories')} - Ingredients: {p.get('ingredients_text')} - Sustainability Score: {score}/100 Explain why this product received this score, and suggest 1–2 greener alternatives or improvements. """ try: res = client.chat.completions.create( model="llama3-8b-8192", messages=[{"role": "user", "content": prompt}], temperature=0.7 ) return res.choices[0].message.content except Exception as e: return f"Groq explanation failed: {str(e)}" # Step 4: Analyze selected product def analyze_selected(product_label): global product_cache index = -1 for i, p in enumerate(product_cache): full_label = f"{p.get('product_name', 'N/A')} | {p.get('packaging', 'N/A')} | {p.get('categories', 'N/A')}" if full_label == product_label: index = i break if index == -1: return 0, {}, "Invalid selection", "" p = product_cache[index] score = score_product(p) breakdown = { "Product Name": p.get("product_name"), "Packaging": p.get("packaging"), "Categories": p.get("categories"), "Ingredients": p.get("ingredients_text"), "Product URL": f"https://world.openfoodfacts.org/product/{p.get('code')}" } alternatives = suggest_greener_alternatives(p) explanation = generate_explanation(p, score) return score, breakdown, "\n".join(alternatives), explanation # Step-5 Suggest Greener Product def suggest_greener_alternatives(p): alternatives = [] name = p.get("product_name", "this product") packaging = (p.get("packaging") or "").lower() categories = (p.get("categories") or "").lower() ingredients = (p.get("ingredients_text") or "").lower() if "plastic" in packaging: alternatives.append("Choose items with recyclable, glass, or biodegradable packaging.") if "meat" in categories: alternatives.append("Consider plant-based or vegan alternatives to reduce emissions.") if "palm oil" in ingredients: alternatives.append("Look for products without palm oil or with certified sustainable sources.") if "ready meal" in categories: alternatives.append("Try preparing similar meals at home using local ingredients.") if not alternatives: alternatives.append(f"{name} is relatively sustainable. You can further reduce impact by buying local or in bulk.") return alternatives # Gradio UI with gr.Blocks() as demo: gr.Markdown("# 🌱 Sustainability Score Analyzer") with gr.Row(): product_input = gr.Textbox(label="Search for a Product") search_btn = gr.Button("Search") product_table = gr.Dataframe(headers=["Product Name", "Packaging", "Categories", "Code"], interactive=False, visible=False, label="Matching Products") product_selector = gr.Dropdown(label="Select a Product from Search Results", choices=[], visible=False) analyze_btn = gr.Button("Analyze Selected Product", visible=False) score_output = gr.Number(label="Sustainability Score") breakdown_output = gr.JSON(label="Product Breakdown") alt_output = gr.Textbox(label="Greener Alternatives") explanation_output = gr.Textbox(label="AI Explanation", lines=8) search_btn.click(fn=search_products, inputs=[product_input], outputs=[product_table, product_selector, analyze_btn, product_selector]) analyze_btn.click(fn=analyze_selected, inputs=[product_selector], outputs=[score_output, breakdown_output, alt_output, explanation_output]) if __name__ == "__main__": demo.launch()