food-analyzer-API / services /analysis_service.py
Prathamesh Sable
bug fix
c43a7a2
from sqlalchemy.orm import Session
from db.models import Marker, Product, Ingredient
from utils.analysis_utils import format_product_analysis_response
from logger_manager import log_info, log_error, log_debug
from interfaces.productModels import ProductAnalysisResponse
from typing import Optional, List
import json
def get_product_ingredients(db: Session, product: Product) -> List[dict]:
"""
Fetch ingredients associated with a product.
Args:
db: Database session
product: Product model instance
Returns:
List of ingredient data dictionaries
"""
ingredient_data = []
try:
# Check if product has ingredient_ids field
ingredient_ids = []
if hasattr(product, 'ingredient_ids') and product.ingredient_ids:
# Handle string or list format
if isinstance(product.ingredient_ids, str):
try:
ingredient_ids = [int(id.strip()) for id in product.ingredient_ids.split(',') if id.strip()]
except:
try:
ingredient_ids = json.loads(product.ingredient_ids)
except:
log_error(f"Failed to parse ingredient_ids: {product.ingredient_ids}")
elif isinstance(product.ingredient_ids, list):
ingredient_ids = product.ingredient_ids
log_info(f"Found {len(ingredient_ids)} ingredient IDs for product {product.id}")
# Fetch ingredients by IDs
for ing_id in ingredient_ids:
ingredient = db.query(Ingredient).filter(Ingredient.id == ing_id).first()
if ingredient:
ingredient_data.append({
"id": ingredient.id,
"name": ingredient.name,
"safety_rating": getattr(ingredient, "safety_rating", 5),
"description": getattr(ingredient, "description", ""),
"health_effects": getattr(ingredient, "health_effects", []),
"allergens": getattr(ingredient, "allergens", [])
})
# If we still don't have ingredients, try looking for a relationship
if not ingredient_data and hasattr(product, 'ingredients') and product.ingredients:
for ingredient in product.ingredients:
ingredient_data.append({
"id": ingredient.id,
"name": ingredient.name,
"safety_rating": getattr(ingredient, "safety_rating", 5),
"description": getattr(ingredient, "description", ""),
"health_effects": getattr(ingredient, "health_effects", []),
"allergens": getattr(ingredient, "allergens", [])
})
return ingredient_data
except Exception as e:
log_error(f"Error fetching ingredients for product {product.id}: {str(e)}")
return []
def get_product_data_by_marker_id(db: Session, target_id: str) -> Optional[ProductAnalysisResponse]:
"""
Retrieves product analysis and ingredient information by marker ID.
Args:
db: The database session.
target_id: The target ID from the marker table.
Returns:
A ProductAnalysisResponse object or None if no product is found.
"""
log_info(f"Attempting to retrieve product data for marker ID: {target_id}")
try:
# Find the marker with the given target_id
marker = db.query(Marker).filter(Marker.vuforia_id == target_id).first()
if not marker:
log_info(f"No marker found for target ID: {target_id}")
return None
# Get the product associated with the marker
product = db.query(Product).filter(Product.id == marker.product_id).first()
if not product:
log_info(f"No product found for product_id: {marker.product_id} linked to marker ID: {target_id}")
return None
log_info(f"Product found for marker ID {target_id}: {product.product_name}")
# Log product fields for debugging
log_info(f"Product fields: ID={product.id}, Name={product.product_name}")
# Get ingredient details if needed
ingredients = get_product_ingredients(db, product)
if ingredients:
log_info(f"Found {len(ingredients)} ingredients for product {product.id}")
# Update product with ingredients if needed
if not hasattr(product, 'ingredients_list') or not product.ingredients_list:
product.ingredients_list = [ing["name"] for ing in ingredients]
# Add ingredient analysis data if needed
if not hasattr(product, 'ingredients_analysis') or not product.ingredients_analysis:
product.ingredients_analysis = ingredients
# Format the response using the utility function
response_data = format_product_analysis_response(product)
return response_data
except Exception as e:
log_error(f"Error retrieving product data for marker ID {target_id}: {str(e)}", e)
return None