Spaces:
Running
Running
File size: 7,407 Bytes
33b10b6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
import sys
from .icmr import analyze_nutrients
from .rda import find_nutrition, rda_analysis, analyze_nutrition_icmr_rda
import os
import json, asyncio
from fastapi import FastAPI, HTTPException
from typing import List, Dict, Any
from pydantic import BaseModel
app = FastAPI()
def find_product_nutrients(product_info_from_db):
#GET Response: {'_id': '6714f0487a0e96d7aae2e839',
#'brandName': 'Parle', 'claims': ['This product does not contain gold'],
#'fssaiLicenseNumbers': [10013022002253],
#'ingredients': [{'metadata': '', 'name': 'Refined Wheat Flour (Maida)', 'percent': '63%'}, {'metadata': '', 'name': 'Sugar', 'percent': ''}, {'metadata': '', 'name': 'Refined Palm Oil', 'percent': ''}, {'metadata': '(Glucose, Levulose)', 'name': 'Invert Sugar Syrup', 'percent': ''}, {'metadata': 'I', 'name': 'Sugar Citric Acid', 'percent': ''}, {'metadata': '', 'name': 'Milk Solids', 'percent': '1%'}, {'metadata': '', 'name': 'Iodised Salt', 'percent': ''}, {'metadata': '503(I), 500 (I)', 'name': 'Raising Agents', 'percent': ''}, {'metadata': '1101 (i)', 'name': 'Flour Treatment Agent', 'percent': ''}, {'metadata': 'Diacetyl Tartaric and Fatty Acid Esters of Glycerol (of Vegetable Origin)', 'name': 'Emulsifier', 'percent': ''}, {'metadata': 'Vanilla', 'name': 'Artificial Flavouring Substances', 'percent': ''}],
#'nutritionalInformation': [{'name': 'Energy', 'unit': 'kcal', 'values': [{'base': 'per 100 g','value': 462}]},
#{'name': 'Protein', 'unit': 'g', 'values': [{'base': 'per 100 g', 'value': 6.7}]},
#{'name': 'Carbohydrate', 'unit': 'g', 'values': [{'base': 'per 100 g', 'value': 76.0}, {'base': 'of which sugars', 'value': 26.9}]},
#{'name': 'Fat', 'unit': 'g', 'values': [{'base': 'per 100 g', 'value': 14.6}, {'base': 'Saturated Fat', 'value': 6.8}, {'base': 'Trans Fat', 'value': 0}]},
#{'name': 'Total Sugars', 'unit': 'g', 'values': [{'base': 'per 100 g', 'value': 27.7}]},
#{'name': 'Added Sugars', 'unit': 'g', 'values': [{'base': 'per 100 g', 'value': 26.9}]},
#{'name': 'Cholesterol', 'unit': 'mg', 'values': [{'base': 'per 100 g', 'value': 0}]},
#{'name': 'Sodium', 'unit': 'mg', 'values': [{'base': 'per 100 g', 'value': 281}]}],
#'packagingSize': {'quantity': 82, 'unit': 'g'},
#'productName': 'Parle-G Gold Biscuits',
#'servingSize': {'quantity': 18.8, 'unit': 'g'},
#'servingsPerPack': 3.98,
#'shelfLife': '7 months from packaging'}
product_type = None
calories = None
sugar = None
total_sugar = None
added_sugar = None
salt = None
serving_size = None
if product_info_from_db["servingSize"]["unit"].lower() == "g":
product_type = "solid"
elif product_info_from_db["servingSize"]["unit"].lower() == "ml":
product_type = "liquid"
serving_size = product_info_from_db["servingSize"]["quantity"]
for item in product_info_from_db["nutritionalInformation"]:
if 'energy' in item['name'].lower():
calories = item['values'][0]['value']
if 'total sugar' in item['name'].lower():
total_sugar = item['values'][0]['value']
if 'added sugar' in item['name'].lower():
added_sugar = item['values'][0]['value']
if 'sugar' in item['name'].lower() and 'added sugar' not in item['name'].lower() and 'total sugar' not in item['name'].lower():
sugar = item['values'][0]['value']
if 'salt' in item['name'].lower():
if salt is None:
salt = 0
salt += item['values'][0]['value']
if salt is None:
salt = 0
for item in product_info_from_db["nutritionalInformation"]:
if 'sodium' in item['name'].lower():
salt += item['values'][0]['value']
if added_sugar is not None and added_sugar > 0 and sugar is None:
sugar = added_sugar
elif total_sugar is not None and total_sugar > 0 and added_sugar is None and sugar is None:
sugar = total_sugar
return product_type, calories, sugar, salt, serving_size
# Define the request body using a simple BaseModel (without complex pydantic models if not needed)
class NutrientAnalysisRequest(BaseModel):
product_info_from_db: dict
@app.post("/api/nutrient-analysis")
async def get_nutrient_analysis(request: NutrientAnalysisRequest):
product_info = request.product_info_from_db
try:
if ("nutritionalInformation" not in product_info or "servingSize" not in product_info or "quantity" not in product_info["servingSize"]):
return {"nutrition_analysis" : ""}
if (len(product_info["nutritionalInformation"]) == 0 or product_info["servingSize"]["quantity"] == 0):
return {"nutrition_analysis" : ""}
nutritional_information = product_info["nutritionalInformation"]
serving_size = product_info["servingSize"]["quantity"]
if nutritional_information:
try:
product_type, calories, sugar, salt, serving_size = find_product_nutrients(product_info)
except Exception as e:
print(f"Error in find_product_nutrients: {str(e)}", exc_info=True)
raise
if product_type is not None and serving_size is not None and serving_size > 0:
# Parallel execution of nutrient analysis tasks
try:
nutrient_analysis, nutrient_analysis_rda_data = await asyncio.gather(
analyze_nutrients(product_type, calories, sugar, salt, serving_size),
rda_analysis(nutritional_information, serving_size)
)
print(f"DEBUG : ICMR based analysis is {nutrient_analysis}")
# Or with a try-except approach
try:
print(f"DEBUG : RDA Data is {nutrient_analysis_rda_data} with userServingSize of type {type(nutrient_analysis_rda_data['userServingSize'])} and nutritionPerServing of type {type(nutrient_analysis_rda_data['nutritionPerServing'])}")
except KeyError as e:
print(f"DEBUG: Missing key in nutrient_analysis_rda_data - {e}")
except Exception as e:
raise
try:
nutrient_analysis_rda = find_nutrition(nutrient_analysis_rda_data)
print(f"DEBUG : RDA based analysis is {nutrient_analysis_rda}")
except Exception as e:
raise
try:
nutritional_level = await analyze_nutrition_icmr_rda(nutrient_analysis, nutrient_analysis_rda)
print(f"DEBUG : ICMR and RDA based analysis is {nutritional_level}")
return {"nutrition_analysis" : nutritional_level}
except Exception as e:
raise
else:
error_msg = "Product information in the db is corrupt"
raise HTTPException(status_code=400, detail=error_msg)
else:
error_msg = "Nutritional information is required"
raise HTTPException(status_code=400, detail=error_msg)
except HTTPException as http_ex:
raise http_ex
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
|