dev2607 commited on
Commit
4cfc61e
·
verified ·
1 Parent(s): afc74eb

Update app.py

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