ParthBhuptani commited on
Commit
87edca7
·
verified ·
1 Parent(s): d88fea3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -0
app.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import os
4
+ from fpdf import FPDF
5
+ import uuid
6
+ import re
7
+ import matplotlib.pyplot as plt
8
+
9
+ # Load your Nebius API key and Folder ID from environment variables
10
+ NEBIUS_API_KEY = os.getenv("NEBIUS_API_KEY") or "YOUR_NEBIUS_API_KEY"
11
+ FOLDER_ID = os.getenv("FOLDER_ID") or "YOUR_FOLDER_ID"
12
+
13
+ def generate_meal(preferences, ingredients, time):
14
+ prompt = f"""
15
+ You're a smart kitchen agent.
16
+
17
+ Given:
18
+ - Dietary preferences: {preferences}
19
+ - Ingredients available: {ingredients}
20
+ - Time available: {time} minutes
21
+
22
+ Tasks:
23
+ 1. Suggest one meal idea
24
+ 2. Provide step-by-step recipe instructions
25
+ 3. List missing ingredients (Shopping List)
26
+ 4. Estimate nutrition (calories, protein, carbs, fat)
27
+
28
+ Output in this format:
29
+ Meal Name: ...
30
+ Steps:
31
+ 1. ...
32
+ 2. ...
33
+ Shopping List:
34
+ - ...
35
+ Nutrition:
36
+ - Calories: ... kcal
37
+ - Protein: ... g
38
+ - Carbs: ... g
39
+ - Fat: ... g
40
+ """
41
+ headers = {
42
+ "Authorization": f"Api-Key {NEBIUS_API_KEY}",
43
+ "Content-Type": "application/json"
44
+ }
45
+ data = {
46
+ "modelUri": f"gpt://{FOLDER_ID}/yandexgpt-lite",
47
+ "completionOptions": {"stream": False, "temperature": 0.7, "maxTokens": 700},
48
+ "messages": [{"role": "user", "text": prompt.strip()}]
49
+ }
50
+ response = requests.post("https://llm.api.cloud.yandex.net/foundationModels/v1/completion",
51
+ headers=headers, json=data)
52
+ try:
53
+ text = response.json()["result"]["alternatives"][0]["message"]["text"]
54
+ except Exception as e:
55
+ return f"❌ Error: Could not fetch recipe. {e}"
56
+ return text
57
+
58
+ def extract_nutrition(recipe_text):
59
+ pattern = r"Calories:\s*([\d\.]+)\s*kcal.*Protein:\s*([\d\.]+)g.*Carbs:\s*([\d\.]+)g.*Fat:\s*([\d\.]+)g"
60
+ match = re.search(pattern, recipe_text.replace("\n", " "))
61
+ if match:
62
+ calories, protein, carbs, fat = map(float, match.groups())
63
+ return {"Calories": calories, "Protein": protein, "Carbs": carbs, "Fat": fat}
64
+ return None
65
+
66
+ def plot_nutrition_chart(nutrition):
67
+ fig, ax = plt.subplots()
68
+ nutrients = list(nutrition.keys())
69
+ values = list(nutrition.values())
70
+ colors = ['#ff9999','#66b3ff','#99ff99','#ffcc99']
71
+ ax.pie(values, labels=nutrients, autopct='%1.1f%%', startangle=140, colors=colors)
72
+ ax.axis('equal')
73
+ plt.tight_layout()
74
+ filename = f"/tmp/nutrition_{uuid.uuid4().hex}.png"
75
+ plt.savefig(filename)
76
+ plt.close(fig)
77
+ return filename
78
+
79
+ def handle_generate(preferences, ingredients, time):
80
+ recipe = generate_meal(preferences, ingredients, time)
81
+ nutrition = extract_nutrition(recipe)
82
+ chart_path = None
83
+ if nutrition:
84
+ chart_path = plot_nutrition_chart(nutrition)
85
+ return recipe, chart_path
86
+
87
+ def save_pdf(recipe_text):
88
+ pdf = FPDF()
89
+ pdf.add_page()
90
+ pdf.set_font("Arial", size=12)
91
+ for line in recipe_text.split('\n'):
92
+ pdf.multi_cell(0, 10, line)
93
+ filename = f"/tmp/AgentChef_Recipe_{uuid.uuid4().hex}.pdf"
94
+ pdf.output(filename)
95
+ return filename
96
+
97
+ with gr.Blocks(css="""
98
+ body { background-color: #111; color: #eee; font-family: 'Segoe UI', sans-serif; }
99
+ .gradio-container { max-width: 900px; margin: auto; }
100
+ .input-label { font-weight: 600; margin-bottom: 5px; }
101
+ .footer { font-size: 0.8rem; color: #666; padding: 10px; text-align: center; }
102
+ @media (max-width: 600px) {
103
+ .gradio-container { padding: 10px; }
104
+ }
105
+ """) as demo:
106
+ gr.Markdown("# 👨‍🍳 AgentChef: AI Recipe Planner & Smart Kitchen Assistant")
107
+
108
+ with gr.Row():
109
+ with gr.Column(scale=1, min_width=200):
110
+ preferences = gr.Textbox(label="🥗 Dietary Preferences", placeholder="e.g. vegetarian, keto")
111
+ ingredients = gr.Textbox(label="🧂 Ingredients You Have", placeholder="e.g. rice, tomato, onion", lines=3)
112
+ mic = gr.Microphone(label="🎤 Speak Ingredients")
113
+ mic.stream(lambda audio: audio if audio else "", inputs=None, outputs=ingredients)
114
+ time = gr.Slider(5, 60, value=20, step=5, label="⏱️ Time Available (minutes)")
115
+ generate_btn = gr.Button("🍽️ Generate Recipe")
116
+
117
+ with gr.Column(scale=1, min_width=300):
118
+ recipe_output = gr.Textbox(label="📝 Recipe Output", lines=15)
119
+ nutrition_chart = gr.Image(label="📊 Nutrition Breakdown", interactive=False)
120
+ pdf_btn = gr.Button("📄 Export as PDF")
121
+
122
+ generate_btn.click(handle_generate,
123
+ inputs=[preferences, ingredients, time],
124
+ outputs=[recipe_output, nutrition_chart])
125
+
126
+ pdf_btn.click(save_pdf, inputs=[recipe_output], outputs=gr.File(label="📥 Download Recipe PDF"))
127
+
128
+ demo.launch()