RajatMalviya commited on
Commit
c005ef1
·
verified ·
1 Parent(s): ed8445d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +219 -9
app.py CHANGED
@@ -1,4 +1,4 @@
1
- from fastapi import FastAPI, File, UploadFile, HTTPException
2
  import google.generativeai as genai
3
  from PIL import Image
4
  import io
@@ -6,6 +6,7 @@ import json
6
  import re
7
  import os
8
  import uvicorn
 
9
 
10
  app = FastAPI()
11
 
@@ -15,17 +16,229 @@ if not api_key:
15
  raise RuntimeError("GOOGLE_API_KEY is not set in the environment variables.")
16
  genai.configure(api_key=api_key)
17
 
 
 
 
 
 
 
 
18
  @app.get("/")
19
  def read_root():
20
- return {"message": "FastAPI is running on Render!"}
21
 
22
  @app.head("/")
23
  async def root_head():
24
  return {} # Empty response for HEAD requests
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  @app.post("/analyze")
27
- async def analyze_food_image(file: UploadFile = File()):
28
- """Analyzes food items in the image using Gemini 1.5 Flash"""
29
 
30
  # Read the uploaded image file
31
  image_bytes = await file.read()
@@ -79,10 +292,7 @@ async def analyze_food_image(file: UploadFile = File()):
79
  """
80
 
81
  # Get response from API
82
- response = model.generate_content([prompt, img]) # Pass image correctly
83
-
84
- # Debugging: Print the raw response
85
- print(f"Raw Response from Gemini: {response}")
86
 
87
  # Extract JSON response
88
  try:
@@ -99,4 +309,4 @@ async def analyze_food_image(file: UploadFile = File()):
99
  # Entry point for Render deployment
100
  if __name__ == "__main__":
101
  port = int(os.getenv("PORT", 7860)) # Render assigns PORT dynamically
102
- uvicorn.run(app, host="0.0.0.0", port=port)
 
1
+ from fastapi import FastAPI, File, UploadFile, HTTPException, Form
2
  import google.generativeai as genai
3
  from PIL import Image
4
  import io
 
6
  import re
7
  import os
8
  import uvicorn
9
+ from enum import Enum
10
 
11
  app = FastAPI()
12
 
 
16
  raise RuntimeError("GOOGLE_API_KEY is not set in the environment variables.")
17
  genai.configure(api_key=api_key)
18
 
19
+ class AnalysisType(str, Enum):
20
+ DETECT_ALLERGENS = "detect_allergens"
21
+ DETAILED_NUTRIENT_INFO = "detailed_nutrient_info"
22
+ LEARN_ABOUT_FOOD = "learn_about_food"
23
+ FUN_FACTS = "fun_facts"
24
+ GENERATE_DISH = "generate_dish"
25
+
26
  @app.get("/")
27
  def read_root():
28
+ return {"message": "Food Analysis API is running!"}
29
 
30
  @app.head("/")
31
  async def root_head():
32
  return {} # Empty response for HEAD requests
33
 
34
+ @app.post("/analyze-food")
35
+ async def analyze_food_image(
36
+ file: UploadFile = File(...),
37
+ analysis_type: AnalysisType = Form(...)
38
+ ):
39
+ """Analyzes food items in the image based on the selected analysis type"""
40
+
41
+ # Read the uploaded image file
42
+ image_bytes = await file.read()
43
+ img = Image.open(io.BytesIO(image_bytes))
44
+
45
+ # Load the generative model
46
+ model = genai.GenerativeModel("gemini-1.5-flash") # Optimized for real-time image processing
47
+
48
+ # Define prompts based on analysis type
49
+ prompts = {
50
+ AnalysisType.DETECT_ALLERGENS: """
51
+ Identify all food items in the given image and list potential allergens.
52
+ Return the response in valid JSON format following this structure:
53
+
54
+ ```json
55
+ {
56
+ "detected_food_items": [
57
+ {
58
+ "food_item": "Detected food name",
59
+ "quantity": "Approximate quantity",
60
+ "potential_allergens": ["allergen1", "allergen2"],
61
+ "allergen_severity": {
62
+ "allergen1": "high/medium/low",
63
+ "allergen2": "high/medium/low"
64
+ },
65
+ "common_cross_reactivity": ["other allergen1", "other allergen2"]
66
+ }
67
+ ]
68
+ }
69
+ ```
70
+
71
+ Ensure the response is valid JSON inside triple backticks.
72
+ """,
73
+
74
+ AnalysisType.DETAILED_NUTRIENT_INFO: """
75
+ Identify all food items in the given image and provide comprehensive nutritional information.
76
+ Return the response in valid JSON format following this structure:
77
+
78
+ ```json
79
+ {
80
+ "detected_food_items": [
81
+ {
82
+ "food_item": "Detected food name",
83
+ "quantity": "Approximate quantity",
84
+ "nutritional_info": {
85
+ "calories_kcal": value,
86
+ "protein_g": value,
87
+ "carbohydrates_g": value,
88
+ "fat_g": value,
89
+ "fiber_g": value,
90
+ "sugar_g": value,
91
+ "sodium_mg": value,
92
+ "potassium_mg": value,
93
+ "calcium_mg": value,
94
+ "iron_mg": value,
95
+ "vitamins": {
96
+ "Vitamin A_mcg": value,
97
+ "Vitamin C_mg": value,
98
+ "Vitamin D_mcg": value,
99
+ "Vitamin E_mg": value,
100
+ "Vitamin K_mcg": value,
101
+ "Vitamin B1_mg": value,
102
+ "Vitamin B2_mg": value,
103
+ "Vitamin B3_mg": value,
104
+ "Vitamin B6_mg": value,
105
+ "Vitamin B12_mcg": value,
106
+ "Folate_mcg": value
107
+ },
108
+ "minerals": {
109
+ "Magnesium_mg": value,
110
+ "Zinc_mg": value,
111
+ "Selenium_mcg": value,
112
+ "Phosphorus_mg": value
113
+ }
114
+ },
115
+ "glycemic_index": value,
116
+ "macronutrient_ratio": {
117
+ "protein_percent": value,
118
+ "carbs_percent": value,
119
+ "fat_percent": value
120
+ }
121
+ }
122
+ ],
123
+ "total_meal_nutrition": {
124
+ "calories_kcal": value,
125
+ "protein_g": value,
126
+ "carbohydrates_g": value,
127
+ "fat_g": value
128
+ }
129
+ }
130
+ ```
131
+
132
+ Ensure the response is valid JSON inside triple backticks.
133
+ """,
134
+
135
+ AnalysisType.LEARN_ABOUT_FOOD: """
136
+ Identify all food items in the given image and provide educational information about them.
137
+ Return the response in valid JSON format following this structure:
138
+
139
+ ```json
140
+ {
141
+ "detected_food_items": [
142
+ {
143
+ "food_item": "Detected food name",
144
+ "origin": "Geographic origin of the food",
145
+ "cultural_significance": "Brief description of cultural importance",
146
+ "history": "Brief history of the food",
147
+ "preparation_methods": ["method1", "method2"],
148
+ "key_ingredients": ["ingredient1", "ingredient2"],
149
+ "nutritional_highlights": ["highlight1", "highlight2"],
150
+ "health_benefits": ["benefit1", "benefit2"],
151
+ "interesting_facts": ["fact1", "fact2"]
152
+ }
153
+ ]
154
+ }
155
+ ```
156
+
157
+ Ensure the response is valid JSON inside triple backticks.
158
+ """,
159
+
160
+ AnalysisType.FUN_FACTS: """
161
+ Identify all food items in the given image and provide fun and interesting facts about them.
162
+ Return the response in valid JSON format following this structure:
163
+
164
+ ```json
165
+ {
166
+ "detected_food_items": [
167
+ {
168
+ "food_item": "Detected food name",
169
+ "fun_facts": [
170
+ "Fun fact 1 about this food",
171
+ "Fun fact 2 about this food",
172
+ "Fun fact 3 about this food"
173
+ ],
174
+ "did_you_know": "An interesting surprising fact",
175
+ "world_records": ["Any world records related to this food"],
176
+ "pop_culture_references": ["How this food appears in movies, TV, etc."],
177
+ "weird_traditions": ["Strange traditions involving this food"]
178
+ }
179
+ ]
180
+ }
181
+ ```
182
+
183
+ Ensure the response is valid JSON inside triple backticks.
184
+ """,
185
+
186
+ AnalysisType.GENERATE_DISH: """
187
+ Identify all food items in the given image and suggest creative dishes that can be made with them.
188
+ Return the response in valid JSON format following this structure:
189
+
190
+ ```json
191
+ {
192
+ "detected_ingredients": ["ingredient1", "ingredient2"],
193
+ "suggested_dishes": [
194
+ {
195
+ "dish_name": "Creative dish name",
196
+ "cuisine_type": "Type of cuisine",
197
+ "difficulty_level": "easy/medium/hard",
198
+ "preparation_time_minutes": value,
199
+ "ingredients": {
200
+ "from_image": ["ingredient1", "ingredient2"],
201
+ "additional_needed": ["extra1", "extra2"]
202
+ },
203
+ "recipe_steps": [
204
+ "Step 1 description",
205
+ "Step 2 description"
206
+ ],
207
+ "nutritional_highlights": ["highlight1", "highlight2"],
208
+ "serving_suggestions": ["suggestion1", "suggestion2"]
209
+ }
210
+ ]
211
+ }
212
+ ```
213
+
214
+ Ensure the response is valid JSON inside triple backticks.
215
+ """
216
+ }
217
+
218
+ # Get the appropriate prompt
219
+ prompt = prompts.get(analysis_type)
220
+ if not prompt:
221
+ raise HTTPException(status_code=400, detail="Invalid analysis type")
222
+
223
+ # Get response from API
224
+ response = model.generate_content([prompt, img])
225
+
226
+ # Extract JSON response
227
+ try:
228
+ # Use regex to extract JSON block
229
+ match = re.search(r'```json\s*(\{.*?\})\s*```', response.text, re.DOTALL)
230
+ if match:
231
+ json_response = match.group(1) # Extract JSON content
232
+ return json.loads(json_response) # Convert to Python dictionary
233
+ else:
234
+ return {"error": "Response does not contain valid JSON format", "raw_response": response.text}
235
+ except json.JSONDecodeError:
236
+ return {"error": "Failed to parse JSON response", "raw_response": response.text}
237
+
238
+ # Keep the original analyze endpoint for backward compatibility
239
  @app.post("/analyze")
240
+ async def analyze_food_image_original(file: UploadFile = File()):
241
+ """Analyzes food items in the image using Gemini 1.5 Flash (original endpoint)"""
242
 
243
  # Read the uploaded image file
244
  image_bytes = await file.read()
 
292
  """
293
 
294
  # Get response from API
295
+ response = model.generate_content([prompt, img])
 
 
 
296
 
297
  # Extract JSON response
298
  try:
 
309
  # Entry point for Render deployment
310
  if __name__ == "__main__":
311
  port = int(os.getenv("PORT", 7860)) # Render assigns PORT dynamically
312
+ uvicorn.run(app, host="0.0.0.0", port=port)