updates on the backend
This commit is contained in:
152
app/api/schemas.py
Normal file
152
app/api/schemas.py
Normal file
@@ -0,0 +1,152 @@
|
||||
"""Pydantic request/response models for the FastAPI layer."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Shared
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class ProductOut(BaseModel):
|
||||
image_id: str
|
||||
image_url: Optional[str] = None
|
||||
image_urls: List[str] = Field(default_factory=list)
|
||||
brand: str
|
||||
product_name: str
|
||||
title: Optional[str] = None
|
||||
category: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
price_range: Optional[str] = None
|
||||
size_variants: List[str] = Field(default_factory=list)
|
||||
providers: List[str] = Field(default_factory=list)
|
||||
highlights: List[str] = Field(default_factory=list)
|
||||
nutrients: List[str] = Field(default_factory=list)
|
||||
fssai_license: Optional[str] = None
|
||||
product_sku: Optional[str] = None
|
||||
sku_source: Optional[str] = None
|
||||
hsn_code: Optional[str] = None
|
||||
final_selling_price: Optional[float] = None
|
||||
selling_price: Optional[float] = None
|
||||
barcode: Optional[str] = None
|
||||
barcode_type: Optional[str] = None
|
||||
|
||||
|
||||
class SourceProductOut(BaseModel):
|
||||
image_id: str
|
||||
image_url: Optional[str] = None
|
||||
image_urls: List[str] = Field(default_factory=list)
|
||||
brand: str
|
||||
product_name: str
|
||||
title: Optional[str] = None
|
||||
category: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
price_range: Optional[str] = None
|
||||
size_variants: List[str] = Field(default_factory=list)
|
||||
providers: List[str] = Field(default_factory=list)
|
||||
highlights: List[str] = Field(default_factory=list)
|
||||
nutrients: List[str] = Field(default_factory=list)
|
||||
fssai_license: Optional[str] = None
|
||||
product_sku: Optional[str] = None
|
||||
sku_source: Optional[str] = None
|
||||
hsn_code: Optional[str] = None
|
||||
final_selling_price: Optional[float] = None
|
||||
selling_price: Optional[float] = None
|
||||
barcode: Optional[str] = None
|
||||
barcode_type: Optional[str] = None
|
||||
similarity: float
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Health
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class HealthOut(BaseModel):
|
||||
status: str
|
||||
database: bool
|
||||
ollama: bool
|
||||
ollama_model: str
|
||||
embeddings_model: str
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Brands / catalog browsing
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class BrandsOut(BaseModel):
|
||||
brands: List[str]
|
||||
|
||||
|
||||
class CategoriesOut(BaseModel):
|
||||
brand: str
|
||||
categories: List[str]
|
||||
|
||||
|
||||
class ProductListOut(BaseModel):
|
||||
brand: str
|
||||
total: int
|
||||
limit: int
|
||||
offset: int
|
||||
products: List[ProductOut]
|
||||
|
||||
|
||||
class AllProductsOut(BaseModel):
|
||||
total: int
|
||||
limit: int
|
||||
offset: int
|
||||
products: List[ProductOut]
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Semantic search (retrieval only, no LLM generation)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class SearchOut(BaseModel):
|
||||
query: str
|
||||
brand: Optional[str] = None
|
||||
results: List[SourceProductOut]
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# RAG chat
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class ChatTurn(BaseModel):
|
||||
role: str = Field(..., description="'user' or 'assistant'")
|
||||
content: str
|
||||
|
||||
|
||||
class ChatRequest(BaseModel):
|
||||
query: str = Field(..., min_length=1, max_length=2000)
|
||||
brand: Optional[str] = Field(None, description="Restrict retrieval to a single brand")
|
||||
category: Optional[str] = Field(None, description="Restrict retrieval to a category")
|
||||
top_k: Optional[int] = Field(None, ge=1, le=15)
|
||||
history: Optional[List[ChatTurn]] = Field(default=None, description="Prior turns for follow-up questions")
|
||||
|
||||
|
||||
class ChatResponseOut(BaseModel):
|
||||
answer: str
|
||||
query: str
|
||||
brand: Optional[str] = None
|
||||
detected_category: Optional[str] = Field(
|
||||
None, description="Product category auto-detected from the query and used to scope retrieval, if any"
|
||||
)
|
||||
sources: List[SourceProductOut]
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Catalog generation (admin/ingestion trigger)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class CatalogGenerateRequest(BaseModel):
|
||||
brand: str = Field(..., min_length=1, max_length=120)
|
||||
max_products: int = Field(50, ge=1, le=300)
|
||||
|
||||
|
||||
class CatalogJobOut(BaseModel):
|
||||
job_id: str
|
||||
brand: str
|
||||
status: str
|
||||
detail: Optional[str] = None
|
||||
Reference in New Issue
Block a user