Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -211,12 +211,38 @@ def _run_inference(image: Image.Image, max_new_tokens: int) -> str:
|
|
| 211 |
|
| 212 |
|
| 213 |
|
|
|
|
| 214 |
def _get_nutrition_from_api(ingredients_text: str) -> dict:
|
| 215 |
-
"""Use Open Food Facts search — no API key needed."""
|
| 216 |
try:
|
| 217 |
-
#
|
| 218 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
response = req_lib.get(
|
| 221 |
"https://world.openfoodfacts.org/cgi/search.pl",
|
| 222 |
params={
|
|
@@ -224,7 +250,8 @@ def _get_nutrition_from_api(ingredients_text: str) -> dict:
|
|
| 224 |
"search_simple": 1,
|
| 225 |
"action": "process",
|
| 226 |
"json": 1,
|
| 227 |
-
"page_size":
|
|
|
|
| 228 |
},
|
| 229 |
timeout=10,
|
| 230 |
)
|
|
@@ -233,21 +260,30 @@ def _get_nutrition_from_api(ingredients_text: str) -> dict:
|
|
| 233 |
products = data.get("products", [])
|
| 234 |
|
| 235 |
if not products:
|
|
|
|
| 236 |
return {}
|
| 237 |
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
except Exception as e:
|
| 247 |
-
logger.warning(f"
|
| 248 |
return {}
|
| 249 |
|
| 250 |
|
|
|
|
| 251 |
def _parse_response(raw: str) -> dict:
|
| 252 |
# FIX: pre-initialize all nutrition keys to None so KeyError never happens
|
| 253 |
result = {
|
|
|
|
| 211 |
|
| 212 |
|
| 213 |
|
| 214 |
+
|
| 215 |
def _get_nutrition_from_api(ingredients_text: str) -> dict:
|
|
|
|
| 216 |
try:
|
| 217 |
+
# Extract the most important food word from the description
|
| 218 |
+
import re
|
| 219 |
+
# Common food words to search for
|
| 220 |
+
food_keywords = [
|
| 221 |
+
"banana", "apple", "orange", "mango", "rice", "chicken", "egg",
|
| 222 |
+
"bread", "milk", "yogurt", "cheese", "pizza", "burger", "salad",
|
| 223 |
+
"pasta", "fish", "beef", "pork", "potato", "tomato", "onion",
|
| 224 |
+
"carrot", "broccoli", "spinach", "lemon", "grape", "strawberry",
|
| 225 |
+
"chocolate", "cake", "cookie", "coffee", "tea", "juice", "soup",
|
| 226 |
+
"sandwich", "taco", "noodle", "tofu", "paneer", "dal", "roti",
|
| 227 |
+
"biryani", "curry", "samosa", "idli", "dosa"
|
| 228 |
+
]
|
| 229 |
+
|
| 230 |
+
text_lower = ingredients_text.lower()
|
| 231 |
+
food_query = None
|
| 232 |
+
|
| 233 |
+
# Find first matching food keyword
|
| 234 |
+
for keyword in food_keywords:
|
| 235 |
+
if keyword in text_lower:
|
| 236 |
+
food_query = keyword
|
| 237 |
+
break
|
| 238 |
|
| 239 |
+
# If no keyword matched, use first 2 words of description
|
| 240 |
+
if not food_query:
|
| 241 |
+
words = re.findall(r'\b[a-zA-Z]{4,}\b', ingredients_text)
|
| 242 |
+
food_query = words[0] if words else ingredients_text[:20]
|
| 243 |
+
|
| 244 |
+
logger.info(f"Searching nutrition for: {food_query}")
|
| 245 |
+
|
| 246 |
response = req_lib.get(
|
| 247 |
"https://world.openfoodfacts.org/cgi/search.pl",
|
| 248 |
params={
|
|
|
|
| 250 |
"search_simple": 1,
|
| 251 |
"action": "process",
|
| 252 |
"json": 1,
|
| 253 |
+
"page_size": 3,
|
| 254 |
+
"fields": "product_name,nutriments",
|
| 255 |
},
|
| 256 |
timeout=10,
|
| 257 |
)
|
|
|
|
| 260 |
products = data.get("products", [])
|
| 261 |
|
| 262 |
if not products:
|
| 263 |
+
logger.warning(f"No products found for: {food_query}")
|
| 264 |
return {}
|
| 265 |
|
| 266 |
+
# Find first product with complete nutrition data
|
| 267 |
+
for product in products:
|
| 268 |
+
nutriments = product.get("nutriments", {})
|
| 269 |
+
calories = nutriments.get("energy-kcal_100g", 0)
|
| 270 |
+
if calories and calories > 0:
|
| 271 |
+
return {
|
| 272 |
+
"calories": round(float(calories), 1),
|
| 273 |
+
"protein_g": round(float(nutriments.get("proteins_100g", 0) or 0), 1),
|
| 274 |
+
"carbs_g": round(float(nutriments.get("carbohydrates_100g", 0) or 0), 1),
|
| 275 |
+
"fat_g": round(float(nutriments.get("fat_100g", 0) or 0), 1),
|
| 276 |
+
"fibre_g": round(float(nutriments.get("fiber_100g", 0) or 0), 1),
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
return {}
|
| 280 |
+
|
| 281 |
except Exception as e:
|
| 282 |
+
logger.warning(f"Nutrition API failed: {e}")
|
| 283 |
return {}
|
| 284 |
|
| 285 |
|
| 286 |
+
|
| 287 |
def _parse_response(raw: str) -> dict:
|
| 288 |
# FIX: pre-initialize all nutrition keys to None so KeyError never happens
|
| 289 |
result = {
|