prathameshks commited on
Commit
103bb6b
·
1 Parent(s): 2e67005

product model update

Browse files
db/models.py CHANGED
@@ -51,16 +51,21 @@ class Product(Base):
51
 
52
  id = Column(Integer, primary_key=True, index=True)
53
  product_name = Column(String, nullable=False)
54
- generic_name = Column(String, nullable=True)
55
- brands = Column(String, nullable=True)
56
  ingredients = Column(JSON, nullable=True)
57
- ingredients_text = Column(String, nullable=True)
58
  ingredients_analysis = Column(JSON, nullable=True)
59
- nutriscore = Column(JSON, nullable=True)
60
- nutrient_levels = Column(JSON, nullable=True)
61
- nutriments = Column(JSON, nullable=True)
62
- data_quality_warnings = Column(JSON, nullable=True)
 
 
 
 
 
 
 
63
 
 
64
  markers: Mapped[List["Marker"]] = relationship(back_populates="product")
65
 
66
 
 
51
 
52
  id = Column(Integer, primary_key=True, index=True)
53
  product_name = Column(String, nullable=False)
 
 
54
  ingredients = Column(JSON, nullable=True)
 
55
  ingredients_analysis = Column(JSON, nullable=True)
56
+ overall_safety_score = Column(Integer, nullable=True)
57
+ suitable_diet_types = Column(String, nullable=True)
58
+ allergy_warnings = Column(JSON, nullable=True)
59
+ usage_recommendations = Column(String, nullable=True)
60
+ health_insights = Column(JSON, nullable=True)
61
+ ingredient_interactions = Column(JSON, nullable=True)
62
+ key_takeaway = Column(String, nullable=True)
63
+ ingredients_count = Column(Integer, nullable=True)
64
+ user_id = Column(Integer, nullable=True)
65
+ timestamp = Column(DateTime, nullable=True)
66
+ ingredient_ids= Column(JSON, nullable=True)
67
 
68
+ data_quality_warnings = Column(JSON, nullable=True)
69
  markers: Mapped[List["Marker"]] = relationship(back_populates="product")
70
 
71
 
db/repositories.py CHANGED
@@ -2,8 +2,10 @@ from sqlalchemy.orm import Session
2
  from sqlalchemy import cast, or_, String
3
  from sqlalchemy.dialects.postgresql import JSONB
4
  from . import models
5
- from interfaces.ingredientModels import IngredientAnalysisResult
6
-
 
 
7
  class IngredientRepository:
8
  def __init__(self, db: Session):
9
  self.db = db
@@ -87,4 +89,28 @@ class IngredientRepository:
87
  self.db.commit()
88
  self.db.refresh(db_ingredient)
89
  return db_ingredient
90
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  from sqlalchemy import cast, or_, String
3
  from sqlalchemy.dialects.postgresql import JSONB
4
  from . import models
5
+ from interfaces.ingredientModels import IngredientAnalysisResult
6
+ from interfaces.productModels import ProductCreate
7
+ from datetime import datetime
8
+
9
  class IngredientRepository:
10
  def __init__(self, db: Session):
11
  self.db = db
 
89
  self.db.commit()
90
  self.db.refresh(db_ingredient)
91
  return db_ingredient
92
+ return None
93
+ class ProductRepository:
94
+ def __init__(self, db: Session):
95
+ self.db = db
96
+
97
+ def add_product(self, product_create: ProductCreate):
98
+ db_product = models.Product(
99
+ product_name=product_create.product_name,
100
+ ingredients=product_create.ingredients,
101
+ overall_safety_score=product_create.overall_safety_score,
102
+ suitable_diet_types=product_create.suitable_diet_types,
103
+ allergy_warnings=product_create.allergy_warnings,
104
+ usage_recommendations=product_create.usage_recommendations,
105
+ health_insights=product_create.health_insights,
106
+ ingredient_interactions=product_create.ingredient_interactions,
107
+ key_takeaway=product_create.key_takeaway,
108
+ ingredients_count=product_create.ingredients_count,
109
+ user_id=product_create.user_id,
110
+ timestamp=product_create.timestamp,
111
+ ingredient_ids=product_create.ingredient_ids
112
+ )
113
+ self.db.add(db_product)
114
+ self.db.commit()
115
+ self.db.refresh(db_product)
116
+ return db_product
interfaces/productModels.py CHANGED
@@ -1,6 +1,24 @@
1
- from typing import List
2
  from pydantic import BaseModel
 
3
 
4
  # Add this class to define the request body structure
5
  class ProductIngredientsRequest(BaseModel):
6
  ingredients: List[str]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Dict
2
  from pydantic import BaseModel
3
+ from datetime import datetime
4
 
5
  # Add this class to define the request body structure
6
  class ProductIngredientsRequest(BaseModel):
7
  ingredients: List[str]
8
+
9
+ class ProductCreate(BaseModel):
10
+ product_name: str
11
+ ingredients: List[str]
12
+ overall_safety_score: int
13
+ suitable_diet_types: str
14
+ allergy_warnings: List[str]
15
+ usage_recommendations: str
16
+ health_insights: Dict[str, List[str]]
17
+ ingredient_interactions: List[str]
18
+ key_takeaway: str
19
+ ingredients_count: int
20
+ user_id: int
21
+ timestamp: datetime
22
+ ingredient_ids: List[int]
23
+
24
+
routers/product.py CHANGED
@@ -6,10 +6,12 @@ from logger_manager import log_info, log_error
6
  from PIL import Image
7
  import os
8
  from services.product_service import ProductService
9
- from db.models import Marker, Ingredient
10
  from sqlalchemy.orm import Session
11
  from db.database import get_db
12
  from fastapi import Depends
 
 
13
  from typing import Generator
14
  from dotenv import load_dotenv
15
  import requests
@@ -126,26 +128,46 @@ async def create_product(
126
  print("Received data:", data)
127
 
128
  # Extract product details and data from request body
129
- product_id = data.get("product_id")
130
-
131
  image_names: List[str] = data.get("image_names")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
 
133
- product_data = {
134
- "ingredients_text": data.get("ingredients_text", ""),
135
- "brands": data.get("brands", ""),
136
- "generic_name": data.get("generic_name", ""),
137
- "nutriscore": data.get("nutriscore", None),
138
- "nutrient_levels": data.get("nutrient_levels", None),
139
- "nutriments": data.get("nutriments", None),
140
- "data_quality_warnings": data.get("data_quality_warnings", None),
141
- }
142
- product_service = ProductService(db)
143
- if not product_id:
144
- product = product_service.add_product(data.get("name"), product_data["ingredients_text"])
145
- product_id = product.id
146
- await add_product_to_database(product_id, image_names, db, product_data)
147
  return JSONResponse(
148
- {"message": "Product data and image processed successfully"}
 
 
 
 
 
 
149
  )
150
 
151
  except HTTPException as e:
 
6
  from PIL import Image
7
  import os
8
  from services.product_service import ProductService
9
+ from db.models import Marker
10
  from sqlalchemy.orm import Session
11
  from db.database import get_db
12
  from fastapi import Depends
13
+ from db.repositories import ProductRepository, IngredientRepository
14
+ from interfaces.productModels import ProductCreate
15
  from typing import Generator
16
  from dotenv import load_dotenv
17
  import requests
 
128
  print("Received data:", data)
129
 
130
  # Extract product details and data from request body
131
+
 
132
  image_names: List[str] = data.get("image_names")
133
+
134
+ # Parse ProductCreate model from data
135
+ product_create_data = ProductCreate(
136
+ product_name=data.get("name"),
137
+ ingredients=data.get("ingredients"),
138
+ overall_safety_score=data.get("overall_safety_score"),
139
+ suitable_diet_types=data.get("suitable_diet_types"),
140
+ allergy_warnings=data.get("allergy_warnings"),
141
+ usage_recommendations=data.get("usage_recommendations"),
142
+ health_insights=data.get("health_insights"),
143
+ ingredient_interactions=data.get("ingredient_interactions"),
144
+ key_takeaway=data.get("key_takeaway"),
145
+ ingredients_count=data.get("ingredients_count"),
146
+ user_id=data.get("user_id"),
147
+ timestamp=data.get("timestamp"),
148
+ ingredient_ids=[]
149
+ )
150
 
151
+ # Find ingredients and append their IDs
152
+ ingredient_repo = IngredientRepository(db)
153
+ for ingredient_name in product_create_data.ingredients:
154
+ ingredient = ingredient_repo.get_ingredient_by_name(ingredient_name)
155
+ if ingredient:
156
+ product_create_data.ingredient_ids.append(ingredient.id)
157
+
158
+ # use repository to add product
159
+ product_repo = ProductRepository(db)
160
+ product = product_repo.add_product(product_create_data)
161
+ product_id=product.id
162
+ await add_product_to_database(product_id, image_names, db, data)
 
 
163
  return JSONResponse(
164
+ {
165
+ "message": "Product data and image processed successfully",
166
+ "product_id":product_id,
167
+ "data":data,
168
+ "product_data": product_create_data.model_dump()
169
+
170
+ }
171
  )
172
 
173
  except HTTPException as e:
services/ingredientFinderAgent.py CHANGED
@@ -681,6 +681,7 @@ class IngredientInfoAgentLangGraph:
681
  # Run each tool directly in sequence and collect results
682
  logger.info(f"Searching local database for {ingredient}")
683
  result = search_local_db.invoke(ingredient)
 
684
  if result.get("found", False):
685
  sources_data.append(result)
686
  logger.info(f"Local DB found data for {ingredient}")
@@ -716,20 +717,10 @@ class IngredientInfoAgentLangGraph:
716
  sources_data.append(result)
717
  logger.info(f"PubChem found data for {ingredient}")
718
 
719
- # Create a state for analysis
720
- state = {
721
- "ingredient": ingredient,
722
- "sources_data": sources_data,
723
- "result": None,
724
- "status": "ready_for_analysis",
725
- "analysis_done": False,
726
- "local_db_checked": True,
727
- "web_search_done": True,
728
- "wikipedia_checked": True,
729
- "open_food_facts_checked": True,
730
- "usda_checked": True,
731
- "pubchem_checked": True
732
- }
733
 
734
  # Run the analysis with the collected data
735
  final_state = analyze_ingredient(state)
@@ -737,6 +728,7 @@ class IngredientInfoAgentLangGraph:
737
  # Extract the result or create a default
738
  if final_state.get("result"):
739
  logger.info(f"Analysis complete for {ingredient}")
 
740
  return IngredientAnalysisResult(**final_state["result"])
741
  else:
742
  logger.info(f"No result in final state for {ingredient}, returning default")
 
681
  # Run each tool directly in sequence and collect results
682
  logger.info(f"Searching local database for {ingredient}")
683
  result = search_local_db.invoke(ingredient)
684
+
685
  if result.get("found", False):
686
  sources_data.append(result)
687
  logger.info(f"Local DB found data for {ingredient}")
 
717
  sources_data.append(result)
718
  logger.info(f"PubChem found data for {ingredient}")
719
 
720
+ state = IngredientState(ingredient=ingredient,
721
+ sources_data=sources_data,
722
+ status="ready_for_analysis"
723
+ )
 
 
 
 
 
 
 
 
 
 
724
 
725
  # Run the analysis with the collected data
726
  final_state = analyze_ingredient(state)
 
728
  # Extract the result or create a default
729
  if final_state.get("result"):
730
  logger.info(f"Analysis complete for {ingredient}")
731
+
732
  return IngredientAnalysisResult(**final_state["result"])
733
  else:
734
  logger.info(f"No result in final state for {ingredient}, returning default")
services/product_service.py CHANGED
@@ -1,14 +1,16 @@
1
  from sqlalchemy.orm import Session
2
  from typing import Optional
3
  from db.models import Product
 
4
 
5
  class ProductService:
6
  def __init__(self, db: Session):
7
  self.db = db
8
 
9
- def add_product(self, name: str, ingredients_text: str) -> Product:
10
- product = Product(product_name=name, ingredients_text=ingredients_text)
11
- self.db.add(product)
 
12
  self.db.commit()
13
  self.db.refresh(product)
14
  return product
 
1
  from sqlalchemy.orm import Session
2
  from typing import Optional
3
  from db.models import Product
4
+ from interfaces.productModels import ProductCreate
5
 
6
  class ProductService:
7
  def __init__(self, db: Session):
8
  self.db = db
9
 
10
+ def add_product(self, product_create: ProductCreate) -> Product:
11
+ product = Product(**product_create.model_dump())
12
+
13
+ self.db.add(product)
14
  self.db.commit()
15
  self.db.refresh(product)
16
  return product