dev2607 commited on
Commit
c168b19
·
verified ·
1 Parent(s): 5f533f4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +285 -48
app.py CHANGED
@@ -1,57 +1,294 @@
1
  import gradio as gr
2
- import google.generativeai as genai
 
 
 
 
 
3
  import os
 
 
4
 
5
- # Load API key from Hugging Face Secret
 
 
 
6
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
7
  genai.configure(api_key=GEMINI_API_KEY)
8
 
9
- def respond(
10
- message,
11
- history: list[tuple[str, str]],
12
- system_message,
13
- max_tokens,
14
- temperature,
15
- top_p,
16
- ):
17
- messages = [{"role": "system", "content": system_message}]
18
-
19
- for val in history:
20
- if val[0]: # User message
21
- messages.append({"role": "user", "content": val[0]})
22
- if val[1]: # Assistant response
23
- messages.append({"role": "assistant", "content": val[1]})
24
-
25
- messages.append({"role": "user", "content": message})
26
-
27
- # Call Gemini API
28
- model = genai.GenerativeModel("gemini-1.5-flash")
29
- response = model.generate_content(message, stream=True)
30
-
31
- output = ""
32
- for chunk in response:
33
- if chunk.text:
34
- output += chunk.text
35
- yield output # Stream response in real-time
36
-
37
- # Gradio Interface
38
- demo = gr.ChatInterface(
39
- respond,
40
- additional_inputs=[
41
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
42
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
43
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
44
- gr.Slider(
45
- minimum=0.1,
46
- maximum=1.0,
47
- value=0.95,
48
- step=0.05,
49
- label="Top-p (nucleus sampling)",
50
- ),
51
- ],
52
- )
53
 
54
- if __name__ == "__main__":
55
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
 
1
  import gradio as gr
2
+ import re
3
+ import numpy as np
4
+ from PIL import Image
5
+ import pytesseract
6
+ import requests
7
+ import json
8
  import os
9
+ from dotenv import load_dotenv
10
+ import google.generativeai as genai
11
 
12
+ # Load environment variables
13
+ load_dotenv()
14
+
15
+ # Configure Gemini API
16
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
17
  genai.configure(api_key=GEMINI_API_KEY)
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ # Function to extract text from images using OCR
21
+ def extract_text_from_image(image):
22
+ try:
23
+ if image is None:
24
+ return "No image captured. Please try again."
25
+ text = pytesseract.image_to_string(image)
26
+ return text
27
+ except Exception as e:
28
+ return f"Error extracting text: {str(e)}"
29
+
30
+ # Function to parse ingredients from text
31
+ def parse_ingredients(text):
32
+ # Basic parsing - split by commas, semicolons, and line breaks
33
+ if not text:
34
+ return []
35
+
36
+ # Clean up the text - remove "Ingredients:" prefix if present
37
+ text = re.sub(r'^ingredients:?\s*', '', text.lower(), flags=re.IGNORECASE)
38
+
39
+ # Split by common ingredient separators
40
+ ingredients = re.split(r',|;|\n', text)
41
+ ingredients = [i.strip().lower() for i in ingredients if i.strip()]
42
+ return ingredients
43
+
44
+ # Function to analyze ingredients with Gemini
45
+ def analyze_ingredients_with_gemini(ingredients_list, health_conditions=None):
46
+ """
47
+ Use Gemini to analyze ingredients and provide health insights
48
+ """
49
+ if not ingredients_list:
50
+ return "No ingredients detected or provided."
51
+
52
+ # Prepare the list of ingredients for the prompt
53
+ ingredients_text = ", ".join(ingredients_list)
54
+
55
+ # Create a prompt for Gemini
56
+ if health_conditions and health_conditions.strip():
57
+ prompt = f"""
58
+ Analyze the following food ingredients for a person with these health conditions: {health_conditions}
59
+
60
+ Ingredients: {ingredients_text}
61
+
62
+ For each ingredient:
63
+ 1. Provide its potential health benefits
64
+ 2. Identify any potential risks
65
+ 3. Note if it may affect the specified health conditions
66
+
67
+ Then provide an overall assessment of the product's suitability for someone with the specified health conditions.
68
+ Format your response in markdown with clear headings and sections.
69
+ """
70
+ else:
71
+ prompt = f"""
72
+ Analyze the following food ingredients:
73
+
74
+ Ingredients: {ingredients_text}
75
+
76
+ For each ingredient:
77
+ 1. Provide its potential health benefits
78
+ 2. Identify any potential risks or common allergens associated with it
79
+
80
+ Then provide an overall assessment of the product's general health profile.
81
+ Format your response in markdown with clear headings and sections.
82
+ """
83
+
84
+ try:
85
+ # Call the Gemini API
86
+ model = genai.GenerativeModel('gemini-pro')
87
+ response = model.generate_content(prompt)
88
+
89
+ # Extract and return the analysis
90
+ analysis = response.text
91
+
92
+ # Add disclaimer
93
+ disclaimer = """
94
+ ## Disclaimer
95
+ This analysis is provided for informational purposes only and should not replace professional medical advice.
96
+ Always consult with a healthcare provider regarding dietary restrictions, allergies, or health conditions.
97
+ """
98
+
99
+ return analysis + disclaimer
100
+
101
+ except Exception as e:
102
+ # Fallback to basic analysis if API call fails
103
+ return f"Error connecting to analysis service: {str(e)}\n\nPlease try again later."
104
+
105
+ # Function to process input based on method (camera, upload, or manual entry)
106
+ def process_input(input_method, text_input, camera_input, upload_input, health_conditions):
107
+ if input_method == "Camera":
108
+ if camera_input is not None:
109
+ extracted_text = extract_text_from_image(camera_input)
110
+ ingredients = parse_ingredients(extracted_text)
111
+ return analyze_ingredients_with_gemini(ingredients, health_conditions)
112
+ else:
113
+ return "No camera image captured. Please try again."
114
+
115
+ elif input_method == "Image Upload":
116
+ if upload_input is not None:
117
+ extracted_text = extract_text_from_image(upload_input)
118
+ ingredients = parse_ingredients(extracted_text)
119
+ return analyze_ingredients_with_gemini(ingredients, health_conditions)
120
+ else:
121
+ return "No image uploaded. Please try again."
122
+
123
+ elif input_method == "Manual Entry":
124
+ if text_input.strip():
125
+ ingredients = parse_ingredients(text_input)
126
+ return analyze_ingredients_with_gemini(ingredients, health_conditions)
127
+ else:
128
+ return "No ingredients entered. Please try again."
129
+
130
+ return "Please provide input using one of the available methods."
131
+
132
+ # Create the Gradio interface
133
+ with gr.Blocks(title="AI Ingredient Scanner") as app:
134
+ gr.Markdown("# AI Ingredient Scanner")
135
+ gr.Markdown("Scan product ingredients and analyze them for health benefits, risks, and potential allergens.")
136
+
137
+ with gr.Row():
138
+ with gr.Column():
139
+ input_method = gr.Radio(
140
+ ["Camera", "Image Upload", "Manual Entry"],
141
+ label="Input Method",
142
+ value="Camera"
143
+ )
144
+
145
+ # Camera input
146
+ camera_input = gr.Image(label="Capture ingredients with camera", type="pil")
147
 
148
+ # Image upload
149
+ upload_input = gr.Image(label="Upload image of ingredients label", type="pil", visible=False)
150
+
151
+ # Text input
152
+ text_input = gr.Textbox(
153
+ label="Enter ingredients list (comma separated)",
154
+ placeholder="milk, sugar, flour, eggs, vanilla extract",
155
+ lines=3,
156
+ visible=False
157
+ )
158
+
159
+ # Health conditions input - now optional and more flexible
160
+ health_conditions = gr.Textbox(
161
+ label="Enter your health concerns (optional)",
162
+ placeholder="diabetes, high blood pressure, peanut allergy, etc.",
163
+ lines=2,
164
+ info="The AI will automatically analyze ingredients for these conditions"
165
+ )
166
+
167
+ analyze_button = gr.Button("Analyze Ingredients")
168
+
169
+ with gr.Column():
170
+ output = gr.Markdown(label="Analysis Results")
171
+ extracted_text_output = gr.Textbox(label="Extracted Text (for verification)", lines=3)
172
+
173
+ # Show/hide inputs based on selection
174
+ def update_visible_inputs(choice):
175
+ return {
176
+ upload_input: choice == "Image Upload",
177
+ camera_input: choice == "Camera",
178
+ text_input: choice == "Manual Entry"
179
+ }
180
+
181
+ input_method.change(update_visible_inputs, input_method, [upload_input, camera_input, text_input])
182
+
183
+ # Extract and display the raw text (for verification purposes)
184
+ def show_extracted_text(input_method, text_input, camera_input, upload_input):
185
+ if input_method == "Camera" and camera_input is not None:
186
+ return extract_text_from_image(camera_input)
187
+ elif input_method == "Image Upload" and upload_input is not None:
188
+ return extract_text_from_image(upload_input)
189
+ elif input_method == "Manual Entry":
190
+ return text_input
191
+ return "No input detected"
192
+
193
+ # Set up event handlers
194
+ analyze_button.click(
195
+ fn=process_input,
196
+ inputs=[input_method, text_input, camera_input, upload_input, health_conditions],
197
+ outputs=output
198
+ )
199
+
200
+ analyze_button.click(
201
+ fn=show_extracted_text,
202
+ inputs=[input_method, text_input, camera_input, upload_input],
203
+ outputs=extracted_text_output
204
+ )
205
+
206
+ gr.Markdown("### How to use")
207
+ gr.Markdown("""
208
+ 1. Choose your input method (Camera, Image Upload, or Manual Entry)
209
+ 2. Take a photo of the ingredients label or enter ingredients manually
210
+ 3. Optionally enter your health concerns
211
+ 4. Click "Analyze Ingredients" to get your personalized analysis
212
+
213
+ The AI will automatically analyze the ingredients, their health implications, and their potential impact on your specific health concerns.
214
+ """)
215
+
216
+ gr.Markdown("### Examples of what you can ask")
217
+ gr.Markdown("""
218
+ The system can handle a wide range of health concerns, such as:
219
+ - General health goals: "trying to reduce sugar intake" or "watching sodium levels"
220
+ - Medical conditions: "diabetes" or "hypertension"
221
+ - Allergies: "peanut allergy" or "shellfish allergy"
222
+ - Dietary restrictions: "vegetarian" or "gluten-free diet"
223
+ - Multiple conditions: "diabetes, high cholesterol, and lactose intolerance"
224
+
225
+ The AI will tailor its analysis to your specific needs.
226
+ """)
227
+
228
+ gr.Markdown("### Tips for best results")
229
+ gr.Markdown("""
230
+ - Hold the camera steady and ensure good lighting
231
+ - Focus directly on the ingredients list
232
+ - Make sure the text is clear and readable
233
+ - Be specific about your health concerns for more targeted analysis
234
+ """)
235
+
236
+ gr.Markdown("### Disclaimer")
237
+ gr.Markdown("""
238
+ This tool is for informational purposes only and should not replace professional medical advice.
239
+ Always consult with a healthcare provider regarding dietary restrictions, allergies, or health conditions.
240
+ """)
241
+
242
+ # Function to run when testing without API key
243
+ def run_with_dummy_llm():
244
+ # Override the LLM function with a dummy version for testing
245
+ global analyze_ingredients_with_gemini
246
+
247
+ def dummy_analyze(ingredients_list, health_conditions=None):
248
+ ingredients_text = ", ".join(ingredients_list)
249
+
250
+ report = f"""
251
+ # Ingredient Analysis Report
252
+
253
+ ## Detected Ingredients
254
+ {", ".join([i.title() for i in ingredients_list])}
255
+
256
+ ## Overview
257
+ This is a simulated analysis since no API key was provided. In the actual application,
258
+ the ingredients would be analyzed by an LLM for their health implications.
259
+
260
+ ## Health Considerations
261
+ """
262
+
263
+ if health_conditions:
264
+ report += f"""
265
+ The analysis would specifically consider these health concerns: {health_conditions}
266
+ """
267
+ else:
268
+ report += """
269
+ No specific health concerns were provided, so a general analysis would be performed.
270
+ """
271
+
272
+ report += """
273
+ ## Disclaimer
274
+ This analysis is provided for informational purposes only and should not replace professional medical advice.
275
+ Always consult with a healthcare provider regarding dietary restrictions, allergies, or health conditions.
276
+ """
277
+
278
+ return report
279
+
280
+ # Replace the real function with the dummy
281
+ analyze_ingredients_with_gemini = dummy_analyze
282
+
283
+ # Launch the app
284
+ app.launch()
285
+
286
+ # Launch the app
287
+ if __name__ == "__main__":
288
+ # Check if API key exists
289
+ if not os.getenv("GEMINI_API_KEY"):
290
+ print("WARNING: No Gemini API key found. Running with simulated LLM responses.")
291
+ run_with_dummy_llm()
292
+ else:
293
+ app.launch()
294