aurora / utils /recommend.py
yasyn14's picture
edited docker and main.py
e7b36c2
import json
import os
from typing import Dict, Any, Optional
import logging
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Global variables
_condition_data = {}
_last_load_time = 0
def _load_condition_data() -> Dict[str, Any]:
"""Load skin condition data from JSON file with proper error handling"""
json_path = 'data/skin_conditions.json'
try:
# Get file modification time to check for changes
mtime = os.path.getmtime(json_path)
# If we've already loaded and file hasn't changed, return cached data
global _condition_data, _last_load_time
if _condition_data and mtime <= _last_load_time:
return _condition_data
# Load and parse JSON file
with open(json_path, encoding='utf-8') as f:
data = json.load(f)
# Index data by lowercase condition name for faster lookups
condition_map = {}
for entry in data:
condition = entry.get("condition", "").strip().lower()
if condition: # Only add entries with a valid condition name
condition_map[condition] = entry
# Update cache
_condition_data = condition_map
_last_load_time = mtime
logger.info(f"Loaded {len(condition_map)} skin conditions from {json_path}")
return condition_map
except FileNotFoundError:
logger.error(f"Skin conditions file not found: {json_path}")
return {}
except json.JSONDecodeError as e:
logger.error(f"Invalid JSON in skin conditions file: {e}")
return {}
except Exception as e:
logger.error(f"Error loading skin conditions: {e}")
return {}
def get_recommended_products(condition_query: str) -> Dict[str, Any]:
"""
Get recommended products for a given skin condition.
Args:
condition_query: The skin condition to look up
Returns:
Dictionary containing condition info and product recommendations,
or empty dict if no match found
"""
if not condition_query:
return {}
# Standardize the query
condition_query = condition_query.strip().lower()
# Load or refresh condition data
condition_data = _load_condition_data()
# Try exact match first (most reliable)
if condition_query in condition_data:
return condition_data[condition_query]
# If exact match fails, try to find the closest match
# This is a fallback for when condition names might have slight variations
for cond_name, entry in condition_data.items():
# Check if query is a substring of a condition or vice versa
if condition_query in cond_name or cond_name in condition_query:
return entry
# No match found
logger.warning(f"No recommendations found for condition: {condition_query}")
return {}