shukdevdatta123 commited on
Commit
a066301
·
verified ·
1 Parent(s): d66206c

Delete v2.txt

Browse files
Files changed (1) hide show
  1. v2.txt +0 -458
v2.txt DELETED
@@ -1,458 +0,0 @@
1
- import gradio as gr
2
- import base64
3
- import requests
4
- import io
5
- from PIL import Image
6
- import json
7
- import os
8
- from together import Together
9
- import tempfile
10
- import uuid
11
-
12
- def encode_image_to_base64(image_path):
13
- """Convert image to base64 encoding"""
14
- with open(image_path, "rb") as image_file:
15
- return base64.b64encode(image_file.read()).decode('utf-8')
16
-
17
- def analyze_single_image(client, img_path):
18
- """Analyze a single image to identify ingredients"""
19
- system_prompt = """You are a culinary expert AI assistant that specializes in identifying ingredients in images.
20
- Your task is to analyze the provided image and list all the food ingredients you can identify.
21
- Be specific and detailed about what you see. Only list ingredients, don't suggest recipes yet."""
22
-
23
- user_prompt = "Please identify all the food ingredients visible in this image. List each ingredient on a new line."
24
-
25
- try:
26
- with open(img_path, "rb") as image_file:
27
- base64_image = base64.b64encode(image_file.read()).decode('utf-8')
28
-
29
- content = [
30
- {"type": "text", "text": user_prompt},
31
- {
32
- "type": "image_url",
33
- "image_url": {
34
- "url": f"data:image/jpeg;base64,{base64_image}"
35
- }
36
- }
37
- ]
38
-
39
- response = client.chat.completions.create(
40
- model="meta-llama/Llama-Vision-Free",
41
- messages=[
42
- {"role": "system", "content": system_prompt},
43
- {"role": "user", "content": content}
44
- ],
45
- max_tokens=500,
46
- temperature=0.2
47
- )
48
-
49
- return response.choices[0].message.content
50
- except Exception as e:
51
- return f"Error analyzing image: {str(e)}"
52
-
53
- def get_recipe_suggestions(api_key, image_paths, num_recipes=3, dietary_restrictions="None", cuisine_preference="Any"):
54
- """Get recipe suggestions based on the uploaded images of ingredients"""
55
- if not api_key:
56
- return "Please provide your Together API key."
57
-
58
- if not image_paths or len(image_paths) == 0:
59
- return "Please upload at least one image of ingredients."
60
-
61
- try:
62
- client = Together(api_key=api_key)
63
-
64
- all_ingredients = []
65
- for img_path in image_paths:
66
- ingredients_text = analyze_single_image(client, img_path)
67
- all_ingredients.append(ingredients_text)
68
-
69
- combined_ingredients = "\n\n".join([f"Image {i+1} ingredients:\n{ingredients}"
70
- for i, ingredients in enumerate(all_ingredients)])
71
-
72
- system_prompt = """You are a culinary expert AI assistant that specializes in creating recipes based on available ingredients.
73
- You will be provided with lists of ingredients identified from multiple images. Your task is to suggest creative,
74
- detailed recipes that use as many of the identified ingredients as possible.
75
-
76
- For each recipe suggestion, include:
77
- 1. Recipe name
78
- 2. Brief description of the dish
79
- 3. Complete ingredients list (including estimated quantities and any additional staple ingredients that might be needed)
80
- 4. Step-by-step cooking instructions
81
- 5. Approximate cooking time
82
- 6. Difficulty level (Easy, Medium, Advanced)
83
- 7. Nutritional highlights
84
-
85
- Consider any dietary restrictions and cuisine preferences mentioned by the user."""
86
-
87
- user_prompt = f"""Based on the following ingredients identified from multiple images, suggest {num_recipes} creative and delicious recipes.
88
-
89
- {combined_ingredients}
90
-
91
- Dietary restrictions to consider: {dietary_restrictions}
92
- Cuisine preference: {cuisine_preference}
93
-
94
- Please be creative with your recipe suggestions and try to use ingredients from multiple images if possible."""
95
-
96
- response = client.chat.completions.create(
97
- model="meta-llama/Llama-Vision-Free",
98
- messages=[
99
- {"role": "system", "content": system_prompt},
100
- {"role": "user", "content": user_prompt}
101
- ],
102
- max_tokens=20000, #2048
103
- temperature=0.7
104
- )
105
-
106
- result = "## 📋 Ingredients Identified\n\n"
107
- result += combined_ingredients
108
- result += "\n\n---\n\n"
109
- result += "## 🍽️ Recipe Suggestions\n\n"
110
- result += response.choices[0].message.content
111
-
112
- return result
113
- except Exception as e:
114
- return f"Error: {str(e)}"
115
-
116
- def update_gallery(files):
117
- """Update the gallery with uploaded image paths"""
118
- if not files or len(files) == 0:
119
- return gr.update(visible=False)
120
- return gr.update(value=files, visible=True)
121
-
122
- def process_recipe_request(api_key, files, num_recipes, dietary_restrictions, cuisine_preference):
123
- """Process the recipe request with uploaded files"""
124
- if not files:
125
- return "Please upload at least one image of ingredients."
126
- return get_recipe_suggestions(api_key, files, num_recipes, dietary_restrictions, cuisine_preference)
127
-
128
- custom_css = """
129
- @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
130
- :root {
131
- --primary-color: #FF6F61; /* Warm coral */
132
- --secondary-color: #4BB543; /* Fresh green */
133
- --accent-color: #F0A500; /* Golden yellow */
134
- --background-color: #F4F4F9; /* Light grayish background */
135
- --text-color: #333333; /* Dark gray text */
136
- --card-background: #FFFFFF; /* White for cards */
137
- --border-radius: 12px;
138
- --font-family: 'Poppins', sans-serif;
139
- --box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 20px;
140
- --hover-shadow: rgba(0, 0, 0, 0.15) 0px 8px 30px;
141
- }
142
- body {
143
- font-family: var(--font-family);
144
- background-color: var(--background-color);
145
- color: var(--text-color);
146
- margin: 0;
147
- padding: 0;
148
- }
149
- .container {
150
- max-width: 1200px;
151
- margin: 0 auto;
152
- padding: 20px;
153
- }
154
- .app-header {
155
- background-color: var(--primary-color);
156
- color: white;
157
- padding: 60px 20px;
158
- text-align: center;
159
- border-radius: 0 0 30px 30px;
160
- box-shadow: var(--box-shadow);
161
- }
162
- .app-title {
163
- font-size: 2.8em;
164
- font-weight: 700;
165
- margin-bottom: 10px;
166
- }
167
- .app-subtitle {
168
- font-size: 1.3em;
169
- font-weight: 300;
170
- max-width: 800px;
171
- margin: 0 auto;
172
- }
173
- .input-section, .output-section {
174
- background-color: var(--card-background);
175
- border-radius: var(--border-radius);
176
- padding: 30px;
177
- box-shadow: var(--box-shadow);
178
- margin-bottom: 30px;
179
- }
180
- .section-header {
181
- font-size: 1.6em;
182
- font-weight: 600;
183
- color: var(--text-color);
184
- margin-bottom: 20px;
185
- border-bottom: 2px solid var(--primary-color);
186
- padding-bottom: 10px;
187
- }
188
- .section-header2 {
189
- font-size: 1.6em;
190
- font-weight: 600;
191
- color: var(--text-color);
192
- border-bottom: 2px solid var(--primary-color);
193
- padding-bottom: 10px;
194
- }
195
- .image-upload-container {
196
- border: 2px dashed var(--secondary-color);
197
- padding: 40px;
198
- text-align: center;
199
- background-color: rgba(75, 181, 67, 0.1);
200
- transition: all 0.3s ease;
201
- }
202
- .image-upload-container:hover {
203
- border-color: var(--primary-color);
204
- background-color: rgba(255, 111, 97, 0.1);
205
- }
206
- button.primary-button {
207
- background-color: var(--primary-color);
208
- color: white;
209
- border: none;
210
- padding: 16px 32px;
211
- border-radius: 6px;
212
- font-size: 1.1em;
213
- cursor: pointer;
214
- transition: all 0.3s ease;
215
- width: 100%;
216
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
217
- }
218
- button.primary-button:hover {
219
- background-color: #E15F52;
220
- box-shadow: var(--hover-shadow);
221
- }
222
- .gallery-container {
223
- display: grid;
224
- grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
225
- gap: 20px;
226
- margin-top: 30px;
227
- }
228
- .gallery-item {
229
- border-radius: var(--border-radius);
230
- overflow: hidden;
231
- box-shadow: var(--box-shadow);
232
- transition: transform 0.3s ease;
233
- aspect-ratio: 1 / 1;
234
- object-fit: cover;
235
- }
236
- .gallery-item:hover {
237
- transform: scale(1.05);
238
- box-shadow: var(--hover-shadow);
239
- }
240
- .recipe-output {
241
- font-size: 1.2em;
242
- line-height: 1.7;
243
- color: var(--text-color);
244
- max-height: 600px;
245
- overflow-y: auto;
246
- padding-right: 15px;
247
- }
248
- .recipe-output h2 {
249
- color: var(--primary-color);
250
- margin-top: 30px;
251
- font-size: 2em;
252
- }
253
- .recipe-output h3 {
254
- color: var(--secondary-color);
255
- font-size: 1.5em;
256
- margin-top: 20px;
257
- }
258
- .loading-container {
259
- display: flex;
260
- flex-direction: column;
261
- justify-content: center;
262
- align-items: center;
263
- position: fixed;
264
- top: 0;
265
- left: 0;
266
- width: 100%;
267
- height: 100%;
268
- background-color: rgba(0, 0, 0, 0.5);
269
- z-index: 1000;
270
- opacity: 0;
271
- visibility: hidden;
272
- transition: opacity 0.3s ease, visibility 0.3s ease;
273
- }
274
- .loading-container.visible {
275
- opacity: 1;
276
- visibility: visible;
277
- }
278
- .loading-spinner {
279
- border: 8px solid #f3f3f3;
280
- border-top: 8px solid var(--primary-color);
281
- border-radius: 50%;
282
- width: 60px;
283
- height: 60px;
284
- animation: spin 1s linear infinite;
285
- }
286
- @keyframes spin {
287
- 0% { transform: rotate(0deg); }
288
- 100% { transform: rotate(360deg); }
289
- }
290
- .loading-text {
291
- color: white;
292
- font-size: 1.3em;
293
- margin-top: 20px;
294
- }
295
- .footer {
296
- background-color: var(--card-background);
297
- padding: 40px 20px;
298
- text-align: center;
299
- color: var(--text-color);
300
- font-size: 1.1em;
301
- box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
302
- }
303
- .footer-content {
304
- max-width: 800px;
305
- margin: 0 auto;
306
- }
307
- .footer-brand {
308
- font-weight: 700;
309
- color: var(--primary-color);
310
- }
311
- .footer-links a {
312
- color: var(--secondary-color);
313
- text-decoration: none;
314
- margin: 0 15px;
315
- transition: color 0.3s ease;
316
- }
317
- .footer-links a:hover {
318
- color: var(--primary-color);
319
- }
320
- """
321
-
322
- html_header = """
323
- <div class="app-header">
324
- <div class="app-title">🍲 Visual Recipe Assistant</div>
325
- <div class="app-subtitle">Upload images of ingredients you have on hand and get personalized recipe suggestions powered by AI</div>
326
- </div>
327
- <div id="loading-overlay" class="loading-container">
328
- <div class="loading-spinner"></div>
329
- <div class="loading-text">Generating your recipes...</div>
330
- </div>
331
- <script>
332
- function showLoading() {
333
- document.getElementById('loading-overlay').classList.add('visible');
334
- }
335
-
336
- function hideLoading() {
337
- document.getElementById('loading-overlay').classList.remove('visible');
338
- }
339
- </script>
340
- """
341
-
342
- html_footer = """
343
- <div class="footer">
344
- <div class="footer-content">
345
- <p><span class="footer-brand">🍲 Visual Recipe Assistant</span></p>
346
- <p>Powered by Meta's Llama-Vision-Free Model & Together AI</p>
347
- <p>Upload multiple ingredient images for more creative recipe combinations</p>
348
- <div class="footer-links">
349
- <a href="#" target="_blank">How It Works</a>
350
- <a href="#" target="_blank">Privacy Policy</a>
351
- <a href="#" target="_blank">Contact Us</a>
352
- </div>
353
- </div>
354
- </div>
355
- <script>
356
- document.addEventListener('DOMContentLoaded', function() {
357
- const submitBtn = document.querySelector('button.primary-button');
358
- if (submitBtn) {
359
- submitBtn.addEventListener('click', function() {
360
- showLoading();
361
- const output = document.querySelector('.recipe-output');
362
- // Check every second for output content
363
- const checkInterval = setInterval(function() {
364
- if (output && output.textContent.trim().length > 0) {
365
- hideLoading();
366
- clearInterval(checkInterval);
367
- clearTimeout(forceHideTimeout);
368
- }
369
- }, 60000);
370
- // Force hide after 120 seconds
371
- const forceHideTimeout = setTimeout(function() {
372
- hideLoading();
373
- clearInterval(checkInterval);
374
- }, 120000); // 120000 milliseconds = 120 seconds
375
- });
376
- }
377
- });
378
- </script>
379
- """
380
-
381
- with gr.Blocks(css=custom_css) as app:
382
- gr.HTML(html_header)
383
-
384
- with gr.Row():
385
- with gr.Column(scale=1):
386
- with gr.Group(elem_classes="input-section"):
387
- gr.HTML('<h3 class="section-header">API Configuration</h3>')
388
- api_key_input = gr.Textbox(
389
- label="Together API Key",
390
- placeholder="Enter your Together API key here...",
391
- type="password",
392
- elem_classes="input-group"
393
- )
394
-
395
- gr.HTML('<h3 class="section-header">Upload Ingredients</h3>')
396
- file_upload = gr.File(
397
- label="Upload images of ingredients",
398
- file_types=["image"],
399
- file_count="multiple",
400
- elem_classes="image-upload-container"
401
- )
402
-
403
- image_input = gr.Gallery(
404
- label="Uploaded Ingredients",
405
- elem_id="ingredient-gallery",
406
- columns=3,
407
- rows=2,
408
- height="auto",
409
- visible=False
410
- )
411
-
412
- gr.HTML('<h3 class="section-header2">Recipe Preferences</h3>')
413
- with gr.Row():
414
- num_recipes = gr.Slider(
415
- minimum=1,
416
- maximum=5,
417
- value=3,
418
- step=1,
419
- label="Number of Recipe Suggestions",
420
- elem_classes="input-group"
421
- )
422
-
423
- with gr.Row():
424
- with gr.Column():
425
- dietary_restrictions = gr.Dropdown(
426
- choices=["None", "Vegetarian", "Vegan", "Gluten-Free", "Dairy-Free", "Low-Carb", "Keto", "Paleo"],
427
- value="None",
428
- label="Dietary Restrictions",
429
- elem_classes="input-group"
430
- )
431
-
432
- with gr.Column():
433
- cuisine_preference = gr.Dropdown(
434
- choices=["Any", "Italian", "Asian", "Mexican", "Mediterranean", "Indian", "American", "French", "Middle Eastern"],
435
- value="Any",
436
- label="Cuisine Preference",
437
- elem_classes="input-group"
438
- )
439
-
440
- submit_button = gr.Button("Get Recipe Suggestions", elem_classes="primary-button")
441
-
442
- with gr.Column(scale=1):
443
- with gr.Group(elem_classes="output-section"):
444
- gr.HTML('<h3 class="section-header">Your Personalized Recipes</h3>')
445
- output = gr.Markdown(elem_classes="recipe-output")
446
-
447
- gr.HTML(html_footer)
448
-
449
- file_upload.change(fn=update_gallery, inputs=file_upload, outputs=image_input)
450
-
451
- submit_button.click(
452
- fn=process_recipe_request,
453
- inputs=[api_key_input, file_upload, num_recipes, dietary_restrictions, cuisine_preference],
454
- outputs=output
455
- )
456
-
457
- if __name__ == "__main__":
458
- app.launch()