import gradio as gr import requests SPOONACULAR_API_KEY = "71259036cfb3405aa5d49c1220a988c5" recipe_id_map = {} # Search recipes def search_recipes(ingredient, cuisine, dietary): global recipe_id_map url = "https://api.spoonacular.com/recipes/complexSearch" params = { "query": ingredient, "cuisine": cuisine, "diet": dietary, "number": 3, "apiKey": SPOONACULAR_API_KEY } res = requests.get(url, params=params) data = res.json() if "results" not in data or not data["results"]: recipe_id_map = {} return gr.update(choices=[], visible=True, label="No recipes found"), gr.update(value="No recipes found.") recipe_id_map = {r["title"]: r["id"] for r in data["results"]} return gr.update(choices=list(recipe_id_map.keys()), visible=True), gr.update(value="Select a recipe from the dropdown.") # Get recipe details def get_recipe_details(selected_title): if not selected_title or selected_title not in recipe_id_map: return "Please select a valid recipe." recipe_id = recipe_id_map[selected_title] url = f"https://api.spoonacular.com/recipes/{recipe_id}/information" params = {"apiKey": SPOONACULAR_API_KEY} res = requests.get(url, params=params) data = res.json() title = data.get("title", "Unknown Title") time = data.get("readyInMinutes", "N/A") instructions = data.get("instructions") or "No instructions available." ingredients_list = data.get("extendedIngredients", []) ingredients = "\n".join([f"- {item.get('original')}" for item in ingredients_list]) return f"### 🍽️ {title}\n**⏱️ Cook Time:** {time} minutes\n\n**📋 Instructions:**\n{instructions}" gr.Markdown("💬 Go to the next tab to ask our chatbot your questions on the recipe!") # Handle chatbot questions def ask_recipe_bot(message, history): # Try to find a recipe ID from previous dropdown results if not recipe_id_map: return "Please use the dropdown tab first to search for a recipe." # Use the first recipe ID from the map recipe_id = list(recipe_id_map.values())[0] url = f"https://api.spoonacular.com/recipes/{recipe_id}/nutritionWidget.json" params = {"apiKey": SPOONACULAR_API_KEY} res = requests.get(url, params=params) if res.status_code != 200: return "Sorry, I couldn't retrieve nutrition info." data = res.json() calories = data.get("calories", "N/A") carbs = data.get("carbs", "N/A") protein = data.get("protein", "N/A") fat = data.get("fat", "N/A") if "calorie" in message.lower(): return f"This recipe has {calories}." elif "protein" in message.lower(): return f"It contains {protein}." elif "carb" in message.lower(): return f"It has {carbs}." elif "fat" in message.lower(): return f"The fat content is {fat}." elif "scale" in message.lower() or "double" in message.lower(): return "You can scale ingredients by multiplying each quantity. For example, to double the recipe, multiply every amount by 2." elif "substitute" in message.lower(): return "Let me know the ingredient you'd like to substitute, and I’ll try to help!" else: return "You can ask about calories, protein, carbs, fat, substitutes, or scaling tips." # Gradio layout with gr.Blocks() as demo: gr.Markdown("## 🧠🍴 The BiteBot") with gr.Tabs(): with gr.Tab("Search Recipes"): with gr.Row(): ingredient = gr.Textbox(label="Preferred Ingredient") cuisine = gr.Textbox(label="Preferred Cuisine") diet = gr.Textbox(label="Dietary Restrictions") search_button = gr.Button("Search Recipes") recipe_dropdown = gr.Dropdown(label="Select a recipe", visible=False) recipe_output = gr.Markdown() search_button.click( fn=search_recipes, inputs=[ingredient, cuisine, diet], outputs=[recipe_dropdown, recipe_output] ) recipe_dropdown.change( fn=get_recipe_details, inputs=recipe_dropdown, outputs=recipe_output ) with gr.Tab("Ask BiteBot"): chatbot = gr.ChatInterface(fn=ask_recipe_bot, chatbot=gr.Chatbot(height=300)) gr.Markdown("💬 Ask about calories, macros, scaling, or substitutions. (Run a recipe search first!)") demo.launch()