dev2607 commited on
Commit
eb7aed5
·
verified ·
1 Parent(s): bfaa1e6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +239 -127
app.py CHANGED
@@ -33,27 +33,130 @@ except:
33
  # Load environment variables
34
  load_dotenv()
35
 
36
- # Mistral API Key
37
- MISTRAL_API_KEY = os.getenv("MISTRAL_API_KEY", "GlrVCBWyvTYjWGKl5jqtK4K41uWWJ79F")
 
38
 
39
- # OpenAI API Key for Product Identification
40
- OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "sk-exampleapikey") # Replace with your actual OpenAI API key
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- # Import and configure Mistral API
43
- def analyze_ingredients_with_mistral(ingredients_list, health_conditions=None):
 
 
 
 
 
 
 
 
 
 
 
44
  """
45
  Use Mistral AI to analyze ingredients and provide health insights.
46
  """
47
- if not ingredients_list:
48
  return "No ingredients detected or provided."
49
 
50
- # Prepare the list of ingredients for the prompt
51
- ingredients_text = ", ".join(ingredients_list)
 
 
 
 
 
 
 
 
52
 
53
  # Create a prompt for Mistral
 
 
54
  if health_conditions and health_conditions.strip():
55
  prompt = f"""
56
- Analyze the following food ingredients for a person with these health conditions: {health_conditions}
57
  Ingredients: {ingredients_text}
58
  For each ingredient:
59
  1. Provide its potential health benefits
@@ -64,7 +167,7 @@ def analyze_ingredients_with_mistral(ingredients_list, health_conditions=None):
64
  """
65
  else:
66
  prompt = f"""
67
- Analyze the following food ingredients:
68
  Ingredients: {ingredients_text}
69
  For each ingredient:
70
  1. Provide its potential health benefits
@@ -84,12 +187,18 @@ def analyze_ingredients_with_mistral(ingredients_list, health_conditions=None):
84
  "temperature": 0.7,
85
  }
86
 
87
- response = requests.post("https://api.mistral.ai/v1/chat/completions", headers=headers, json=data)
 
 
 
 
 
88
 
89
  if response.status_code == 200:
90
  analysis = response.json()['choices'][0]['message']['content']
91
  else:
92
- return dummy_analyze(ingredients_list, health_conditions) + f"\n\n(Using fallback analysis: Mistral API Error - {response.status_code} - {response.text})"
 
93
 
94
  # Add disclaimer
95
  disclaimer = """
@@ -101,21 +210,25 @@ def analyze_ingredients_with_mistral(ingredients_list, health_conditions=None):
101
  return analysis + disclaimer
102
 
103
  except Exception as e:
 
104
  # Fallback to basic analysis if API call fails
105
- return dummy_analyze(ingredients_list, health_conditions) + f"\n\n(Using fallback analysis: {str(e)})"
106
 
107
 
108
  # Dummy analysis function for when API is not available
109
  def dummy_analyze(ingredients_list, health_conditions=None):
110
- ingredients_text = ", ".join(ingredients_list)
 
 
 
111
 
112
  report = f"""
113
  # Ingredient Analysis Report
114
  ## Detected Ingredients
115
- {", ".join([i.title() for i in ingredients_list])}
116
  ## Overview
117
- This is a simulated analysis since the Mistral API call failed. In the actual application,
118
- the ingredients would be analyzed by Mistral for their health implications.
119
  ## Health Considerations
120
  """
121
 
@@ -283,127 +396,99 @@ def parse_ingredients(text):
283
 
284
  return cleaned_ingredients
285
 
286
- def identify_product_and_get_ingredients(image):
287
- """
288
- Identifies the product from the image using OpenAI and retrieves ingredients.
289
- """
290
- try:
291
- # Encode the image to base64
292
- buffered = io.BytesIO()
293
- image.save(buffered, format="JPEG")
294
- img_str = base64.b64encode(buffered.getvalue()).decode('utf-8')
295
 
296
- headers = {
297
- "Content-Type": "application/json",
298
- "Authorization": f"Bearer {OPENAI_API_KEY}"
299
- }
 
 
300
 
301
- payload = {
302
- "model": "gpt-4-vision-preview",
303
- "messages": [
304
- {
305
- "role": "user",
306
- "content": [
307
- {
308
- "type": "text",
309
- "text": "Identify the food product in this image. If identifiable, also find its ingredients."
310
- },
311
- {
312
- "type": "image_url",
313
- "image_url": {
314
- "url": f"data:image/jpeg;base64,{img_str}"
315
- }
316
- }
317
- ]
318
- }
319
- ],
320
- "max_tokens": 500
321
- }
322
-
323
- response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)
324
- response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
325
 
326
- data = response.json()
327
- response_text = data['choices'][0]['message']['content']
 
 
328
 
329
- # Attempt to extract ingredients from the response
330
- ingredients_match = re.search(r"Ingredients:\s*(.+)", response_text, re.IGNORECASE)
331
- if ingredients_match:
332
- ingredients_text = ingredients_match.group(1)
333
- ingredients = parse_ingredients(ingredients_text)
334
- return ingredients, response_text
335
  else:
336
- # If ingredients not found, return the full response for further handling
337
- return None, response_text
338
 
339
- except requests.exceptions.RequestException as e:
340
- return None, f"Error during OpenAI API request: {e}"
341
- except json.JSONDecodeError as e:
342
- return None, f"Error decoding JSON response from OpenAI: {e}"
343
- except Exception as e:
344
- return None, f"Error identifying product: {e}"
 
 
 
 
 
 
 
 
345
 
346
- # Function to process input based on method (camera, upload, or manual entry)
347
- def process_input(input_method, text_input, camera_input, upload_input, health_conditions):
348
- if input_method == "Camera":
349
  if camera_input is not None:
350
- ingredients, response_text = identify_product_and_get_ingredients(camera_input)
351
 
352
- if ingredients:
353
- return analyze_ingredients_with_mistral(ingredients, health_conditions), response_text
354
- else:
355
- return f"Could not identify ingredients from the image. Response from OpenAI:\n\n{response_text}", response_text
356
 
357
- else:
358
- return "No camera image captured. Please try again.", ""
359
 
360
- elif input_method == "Image Upload":
361
- if upload_input is not None:
362
- ingredients, response_text = identify_product_and_get_ingredients(upload_input)
363
- if ingredients:
364
- return analyze_ingredients_with_mistral(ingredients, health_conditions), response_text
365
- else:
366
- return f"Could not identify ingredients from the image. Response from OpenAI:\n\n{response_text}", response_text
367
 
368
- else:
369
- return "No image uploaded. Please try again.", ""
370
 
371
- elif input_method == "Manual Entry":
372
- if text_input and text_input.strip():
373
- ingredients = parse_ingredients(text_input)
374
- return analyze_ingredients_with_mistral(ingredients, health_conditions), ""
375
  else:
376
- return "No ingredients entered. Please try again.", ""
377
 
378
- return "Please provide input using one of the available methods.", ""
379
 
380
  # Create the Gradio interface
381
  with gr.Blocks(title="AI Ingredient Scanner") as app:
382
  gr.Markdown("# AI Ingredient Scanner")
383
- gr.Markdown("Scan product ingredients and analyze them for health benefits, risks, and potential allergens.")
384
 
385
  with gr.Row():
386
  with gr.Column():
387
  input_method = gr.Radio(
388
- ["Camera", "Image Upload", "Manual Entry"],
389
  label="Input Method",
390
- value="Camera"
 
391
  )
392
 
393
- # Camera input
394
- camera_input = gr.Image(label="Capture image of product", type="pil", visible=True)
395
-
396
- # Image upload
397
- upload_input = gr.Image(label="Upload image of product", type="pil", visible=False)
398
-
399
- # Text input
400
- text_input = gr.Textbox(
401
- label="Enter ingredients list (comma separated)",
402
- placeholder="milk, sugar, flour, eggs, vanilla extract",
403
- lines=3,
404
  visible=False
405
  )
406
 
 
 
 
 
 
 
407
  # Health conditions input - now optional and more flexible
408
  health_conditions = gr.Textbox(
409
  label="Enter your health concerns (optional)",
@@ -412,36 +497,64 @@ with gr.Blocks(title="AI Ingredient Scanner") as app:
412
  info="The AI will automatically analyze ingredients for these conditions"
413
  )
414
 
415
- analyze_button = gr.Button("Analyze Ingredients")
416
 
417
  with gr.Column():
418
  output = gr.Markdown(label="Analysis Results")
419
- extracted_text_output = gr.Textbox(label="Extracted Response from OpenAI", lines=5)
420
 
421
  # Show/hide inputs based on selection
422
  def update_visible_inputs(choice):
423
  return {
424
- upload_input: gr.update(visible=(choice == "Image Upload")),
425
- camera_input: gr.update(visible=(choice == "Camera")),
426
- text_input: gr.update(visible=(choice == "Manual Entry"))
427
  }
428
 
429
- input_method.change(update_visible_inputs, input_method, [upload_input, camera_input, text_input])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
430
 
431
  # Set up event handlers
432
  analyze_button.click(
433
  fn=process_input,
434
- inputs=[input_method, text_input, camera_input, upload_input, health_conditions],
435
- outputs=[output, extracted_text_output]
 
 
 
 
 
 
436
  )
437
 
438
  gr.Markdown("### How to use")
439
  gr.Markdown("""
440
- 1. Choose your input method (Camera, Image Upload, or Manual Entry)
441
- 2. Take a photo of the product or upload an image, or enter ingredients manually
442
- 3. Optionally enter your health concerns
443
- 4. Click "Analyze Ingredients" to get your personalized analysis
444
- The AI will automatically identify the product and analyze the ingredients, their health implications, and their potential impact on your specific health concerns.
 
 
 
445
  """)
446
 
447
  gr.Markdown("### Examples of what you can ask")
@@ -458,8 +571,9 @@ with gr.Blocks(title="AI Ingredient Scanner") as app:
458
  gr.Markdown("### Tips for best results")
459
  gr.Markdown("""
460
  - Hold the camera steady and ensure good lighting
461
- - Focus directly on the product, including its label
462
- - Make sure the product is clearly visible
 
463
  - Be specific about your health concerns for more targeted analysis
464
  """)
465
 
@@ -471,6 +585,4 @@ with gr.Blocks(title="AI Ingredient Scanner") as app:
471
 
472
  # Launch the app
473
  if __name__ == "__main__":
474
- import io
475
- import base64
476
  app.launch()
 
33
  # Load environment variables
34
  load_dotenv()
35
 
36
+ # API Keys
37
+ MISTRAL_API_KEY = "GlrVCBWyvTYjWGKl5jqtK4K41uWWJ79F"
38
+ META_LLAMA_API_KEY = "22068836-e455-47e7-8293-373f9e4c84fb" # Updated API key
39
 
40
+ # Meta LLaMA API for ingredient extraction from product names/images
41
+ def extract_ingredients_with_llama(image=None, product_name=None):
42
+ """
43
+ Use Meta's LLaMA API to extract ingredients from a product image or name
44
+ """
45
+ if not image and not product_name:
46
+ return "No product information provided. Please provide an image or product name."
47
+
48
+ # Prepare API call to Meta LLaMA
49
+ headers = {
50
+ "Authorization": f"Bearer {META_LLAMA_API_KEY}",
51
+ "Content-Type": "application/json"
52
+ }
53
+
54
+ # Create prompt based on what's provided
55
+ if image:
56
+ # Convert image to base64 for API
57
+ import base64
58
+ from io import BytesIO
59
+
60
+ buffered = BytesIO()
61
+ image.save(buffered, format="JPEG")
62
+ img_str = base64.b64encode(buffered.getvalue()).decode('utf-8')
63
+
64
+ prompt = [
65
+ {"role": "system", "content": "You are an expert at identifying food products and their ingredients from images. Extract the product name and list all ingredients you can identify."},
66
+ {"role": "user", "content": [
67
+ {"type": "text", "text": "Look at this food product image and list all the ingredients it contains. If you can identify the product name, mention that first, then list all ingredients in a comma-separated format."},
68
+ {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{img_str}"}}
69
+ ]}
70
+ ]
71
+ else:
72
+ # Product name provided
73
+ prompt = [
74
+ {"role": "system", "content": "You are an expert at identifying food product ingredients. Your task is to list all common ingredients for the specified product."},
75
+ {"role": "user", "content": f"Please list all the common ingredients typically found in {product_name}. Provide the ingredients in a comma-separated format."}
76
+ ]
77
+
78
+ # Call Meta LLaMA API
79
+ try:
80
+ data = {
81
+ "model": "meta-llama/Llama-3-8b-hf", # Use an appropriate model
82
+ "messages": prompt,
83
+ "temperature": 0.2, # Lower temperature for more factual responses
84
+ "max_tokens": 800
85
+ }
86
+
87
+ # Add logging for debugging
88
+ print(f"Sending request to LLaMA API with data structure: {json.dumps(data)[:300]}...")
89
+
90
+ response = requests.post(
91
+ "https://api.llama-api.com/chat/completions", # Replace with correct endpoint if different
92
+ headers=headers,
93
+ json=data,
94
+ timeout=30 # Add timeout to prevent hanging
95
+ )
96
+
97
+ if response.status_code == 200:
98
+ text_response = response.json()['choices'][0]['message']['content']
99
+ print(f"LLaMA API response received: {text_response[:100]}...")
100
+
101
+ # Extract ingredients from the response
102
+ # Look for a list of ingredients following common patterns
103
+ ingredients_section = re.search(r'ingredients:?\s*([^\.]+)', text_response, re.IGNORECASE)
104
+ if ingredients_section:
105
+ ingredients_text = ingredients_section.group(1)
106
+ else:
107
+ # If no explicit "ingredients:" section, try to identify comma-separated lists
108
+ # and take the longest one as it's likely to be the ingredients list
109
+ comma_lists = re.findall(r'([^\.;:]+(?:,\s*[^\.;:]+){2,})', text_response)
110
+ if comma_lists:
111
+ ingredients_text = max(comma_lists, key=len)
112
+ else:
113
+ ingredients_text = text_response # Use full response if no list found
114
+
115
+ # Parse the ingredients
116
+ ingredients = parse_ingredients(ingredients_text)
117
+
118
+ # Extract product name if possible
119
+ product_match = re.search(r'product(?:\s+name)?(?:\s+is)?:?\s*([^\.;,\n]+)', text_response, re.IGNORECASE)
120
+ if product_match:
121
+ product_name = product_match.group(1).strip()
122
+ return ingredients, product_name
123
 
124
+ return ingredients, None
125
+
126
+ else:
127
+ print(f"Error response from LLaMA API: {response.status_code} - {response.text}")
128
+ # Fall back to dummy analysis on error
129
+ return f"Error calling Meta LLaMA API: {response.status_code} - {response.text}", None
130
+
131
+ except Exception as e:
132
+ print(f"Exception in LLaMA API call: {str(e)}")
133
+ return f"Error extracting ingredients with LLaMA: {str(e)}", None
134
+
135
+ # Mistral API for ingredient analysis
136
+ def analyze_ingredients_with_mistral(ingredients_list, health_conditions=None, product_name=None):
137
  """
138
  Use Mistral AI to analyze ingredients and provide health insights.
139
  """
140
+ if not ingredients_list or (isinstance(ingredients_list, list) and len(ingredients_list) == 0):
141
  return "No ingredients detected or provided."
142
 
143
+ # Handle error messages that might have been passed
144
+ if isinstance(ingredients_list, str) and "Error" in ingredients_list:
145
+ # Fall back to dummy analysis if there was an error
146
+ return dummy_analyze(product_name if product_name else "Unknown product", health_conditions)
147
+
148
+ # Convert to string if it's a list
149
+ if isinstance(ingredients_list, list):
150
+ ingredients_text = ", ".join(ingredients_list)
151
+ else:
152
+ ingredients_text = ingredients_list
153
 
154
  # Create a prompt for Mistral
155
+ product_info = f"Product Name: {product_name}\n" if product_name else ""
156
+
157
  if health_conditions and health_conditions.strip():
158
  prompt = f"""
159
+ {product_info}Analyze the following food ingredients for a person with these health conditions: {health_conditions}
160
  Ingredients: {ingredients_text}
161
  For each ingredient:
162
  1. Provide its potential health benefits
 
167
  """
168
  else:
169
  prompt = f"""
170
+ {product_info}Analyze the following food ingredients:
171
  Ingredients: {ingredients_text}
172
  For each ingredient:
173
  1. Provide its potential health benefits
 
187
  "temperature": 0.7,
188
  }
189
 
190
+ response = requests.post(
191
+ "https://api.mistral.ai/v1/chat/completions",
192
+ headers=headers,
193
+ json=data,
194
+ timeout=30
195
+ )
196
 
197
  if response.status_code == 200:
198
  analysis = response.json()['choices'][0]['message']['content']
199
  else:
200
+ print(f"Error response from Mistral API: {response.status_code} - {response.text}")
201
+ return dummy_analyze(ingredients_list if isinstance(ingredients_list, list) else [ingredients_text], health_conditions) + f"\n\n(Using fallback analysis: Mistral API Error - {response.status_code} - {response.text})"
202
 
203
  # Add disclaimer
204
  disclaimer = """
 
210
  return analysis + disclaimer
211
 
212
  except Exception as e:
213
+ print(f"Exception in Mistral API call: {str(e)}")
214
  # Fallback to basic analysis if API call fails
215
+ return dummy_analyze(ingredients_list if isinstance(ingredients_list, list) else [ingredients_text], health_conditions) + f"\n\n(Using fallback analysis: {str(e)})"
216
 
217
 
218
  # Dummy analysis function for when API is not available
219
  def dummy_analyze(ingredients_list, health_conditions=None):
220
+ if isinstance(ingredients_list, str):
221
+ ingredients_text = ingredients_list
222
+ else:
223
+ ingredients_text = ", ".join(ingredients_list)
224
 
225
  report = f"""
226
  # Ingredient Analysis Report
227
  ## Detected Ingredients
228
+ {", ".join([i.title() for i in ingredients_list]) if isinstance(ingredients_list, list) else ingredients_text}
229
  ## Overview
230
+ This is a simulated analysis since the API call failed. In the actual application,
231
+ the ingredients would be analyzed by an AI model for their health implications.
232
  ## Health Considerations
233
  """
234
 
 
396
 
397
  return cleaned_ingredients
398
 
 
 
 
 
 
 
 
 
 
399
 
400
+ # Function to process input based on method (camera, product photo, or product name)
401
+ def process_input(input_method, product_name, camera_input, product_photo, health_conditions):
402
+ if input_method == "Product Photo":
403
+ if product_photo is not None:
404
+ # Use Meta LLaMA to extract ingredients from product photo
405
+ ingredients, detected_product = extract_ingredients_with_llama(image=product_photo)
406
 
407
+ # If error occurred, use fallback analysis
408
+ if isinstance(ingredients, str) and "Error" in ingredients:
409
+ print(f"LLaMA API error, using fallback: {ingredients}")
410
+ return f"Error extracting ingredients. Using fallback analysis.\n\n{dummy_analyze('Unknown food product', health_conditions)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
 
412
+ # Add product name info if detected
413
+ product_info = ""
414
+ if detected_product:
415
+ product_info = f"## Product: {detected_product}\n\n"
416
 
417
+ # Analyze ingredients
418
+ analysis = analyze_ingredients_with_mistral(ingredients, health_conditions, detected_product)
419
+ return product_info + analysis
 
 
 
420
  else:
421
+ return "No product image captured. Please try again."
 
422
 
423
+ elif input_method == "Product Name":
424
+ if product_name and product_name.strip():
425
+ # Use Meta LLaMA to extract ingredients based on product name
426
+ ingredients, _ = extract_ingredients_with_llama(product_name=product_name)
427
+
428
+ # If error occurred, use fallback analysis
429
+ if isinstance(ingredients, str) and "Error" in ingredients:
430
+ print(f"LLaMA API error, using fallback: {ingredients}")
431
+ return f"Error extracting ingredients. Using fallback analysis.\n\n{dummy_analyze(product_name, health_conditions)}"
432
+
433
+ # Analyze ingredients
434
+ return analyze_ingredients_with_mistral(ingredients, health_conditions, product_name)
435
+ else:
436
+ return "No product name entered. Please try again."
437
 
438
+ elif input_method == "Camera (Ingredients Label)":
 
 
439
  if camera_input is not None:
440
+ extracted_text = extract_text_from_image(camera_input)
441
 
442
+ # If OCR fails, try using Meta LLaMA API as backup
443
+ if "Error" in extracted_text or "No text could be extracted" in extracted_text:
444
+ print(f"OCR failed, trying LLaMA API backup: {extracted_text}")
445
+ ingredients, detected_product = extract_ingredients_with_llama(image=camera_input)
446
 
447
+ if isinstance(ingredients, str) and "Error" in ingredients:
448
+ return f"Could not extract ingredients from image. Using fallback analysis.\n\n{dummy_analyze('Unknown food product', health_conditions)}"
449
 
450
+ product_info = ""
451
+ if detected_product:
452
+ product_info = f"## Product: {detected_product}\n\n"
 
 
 
 
453
 
454
+ analysis = analyze_ingredients_with_mistral(ingredients, health_conditions, detected_product)
455
+ return product_info + "Ingredients extracted using AI image analysis.\n\n" + analysis
456
 
457
+ # If OCR succeeded, parse ingredients normally
458
+ ingredients = parse_ingredients(extracted_text)
459
+ return analyze_ingredients_with_mistral(ingredients, health_conditions)
 
460
  else:
461
+ return "No camera image captured. Please try again."
462
 
463
+ return "Please provide input using one of the available methods."
464
 
465
  # Create the Gradio interface
466
  with gr.Blocks(title="AI Ingredient Scanner") as app:
467
  gr.Markdown("# AI Ingredient Scanner")
468
+ gr.Markdown("Analyze product ingredients for health benefits, risks, and potential allergens. Just take a photo of the product or enter its name!")
469
 
470
  with gr.Row():
471
  with gr.Column():
472
  input_method = gr.Radio(
473
+ ["Product Photo", "Product Name", "Camera (Ingredients Label)"],
474
  label="Input Method",
475
+ value="Product Photo",
476
+ info="Choose how you want to identify the product"
477
  )
478
 
479
+ # Product name input
480
+ product_name = gr.Textbox(
481
+ label="Enter product name",
482
+ placeholder="e.g., Coca-Cola, Oreo Cookies, Lay's Potato Chips",
 
 
 
 
 
 
 
483
  visible=False
484
  )
485
 
486
+ # Product photo capture
487
+ product_photo = gr.Image(label="Take a photo of the product", type="pil", visible=True)
488
+
489
+ # Camera input for ingredients label (original functionality)
490
+ camera_input = gr.Image(label="Capture ingredients label with camera", type="pil", visible=False)
491
+
492
  # Health conditions input - now optional and more flexible
493
  health_conditions = gr.Textbox(
494
  label="Enter your health concerns (optional)",
 
497
  info="The AI will automatically analyze ingredients for these conditions"
498
  )
499
 
500
+ analyze_button = gr.Button("Analyze Product")
501
 
502
  with gr.Column():
503
  output = gr.Markdown(label="Analysis Results")
504
+ extracted_info = gr.Textbox(label="Extracted Information (for verification)", lines=3)
505
 
506
  # Show/hide inputs based on selection
507
  def update_visible_inputs(choice):
508
  return {
509
+ product_photo: gr.update(visible=(choice == "Product Photo")),
510
+ product_name: gr.update(visible=(choice == "Product Name")),
511
+ camera_input: gr.update(visible=(choice == "Camera (Ingredients Label)")),
512
  }
513
 
514
+ input_method.change(update_visible_inputs, input_method, [product_photo, product_name, camera_input])
515
+
516
+ # Display extracted information (for verification purposes)
517
+ def show_extracted_info(input_method, product_name, camera_input, product_photo):
518
+ if input_method == "Product Photo" and product_photo is not None:
519
+ ingredients, product = extract_ingredients_with_llama(image=product_photo)
520
+ if isinstance(ingredients, list):
521
+ return f"Product: {product if product else 'Unknown'}\nIngredients: {', '.join(ingredients)}"
522
+ else:
523
+ return ingredients
524
+ elif input_method == "Product Name" and product_name:
525
+ ingredients, _ = extract_ingredients_with_llama(product_name=product_name)
526
+ if isinstance(ingredients, list):
527
+ return f"Product: {product_name}\nIngredients: {', '.join(ingredients)}"
528
+ else:
529
+ return ingredients
530
+ elif input_method == "Camera (Ingredients Label)" and camera_input is not None:
531
+ extracted_text = extract_text_from_image(camera_input)
532
+ return extracted_text
533
+ return "No input detected"
534
 
535
  # Set up event handlers
536
  analyze_button.click(
537
  fn=process_input,
538
+ inputs=[input_method, product_name, camera_input, product_photo, health_conditions],
539
+ outputs=output
540
+ )
541
+
542
+ analyze_button.click(
543
+ fn=show_extracted_info,
544
+ inputs=[input_method, product_name, camera_input, product_photo],
545
+ outputs=extracted_info
546
  )
547
 
548
  gr.Markdown("### How to use")
549
  gr.Markdown("""
550
+ 1. Choose your input method:
551
+ - **Product Photo**: Take a photo of the entire product (front, back, or packaging)
552
+ - **Product Name**: Simply enter the name of the product
553
+ - **Camera (Ingredients Label)**: Traditional method - take a photo of the ingredients list
554
+ 2. Optionally enter your health concerns
555
+ 3. Click "Analyze Product" to get your personalized analysis
556
+
557
+ The AI will automatically detect the product, extract its ingredients, and analyze them.
558
  """)
559
 
560
  gr.Markdown("### Examples of what you can ask")
 
571
  gr.Markdown("### Tips for best results")
572
  gr.Markdown("""
573
  - Hold the camera steady and ensure good lighting
574
+ - For Product Photo: Capture the entire product package clearly
575
+ - For Product Name: Be specific (e.g., "Honey Nut Cheerios" instead of just "Cheerios")
576
+ - For Ingredients Label: Focus directly on the ingredients list text
577
  - Be specific about your health concerns for more targeted analysis
578
  """)
579
 
 
585
 
586
  # Launch the app
587
  if __name__ == "__main__":
 
 
588
  app.launch()