Spaces:
Sleeping
Sleeping
""" | |
This file defines the data structures (schemas) for the recommender system's API using Pydantic. | |
It ensures that data exchanged with the API (requests and responses) adheres to a specific format, | |
providing benefits like automatic data validation, serialization/deserialization, | |
and clear API documentation. | |
""" | |
from pydantic import BaseModel, Field, validator | |
from typing import List, Optional, Any, Union | |
from src.config.settings import DEFAULT_K # For default 'k' value | |
class MsgPayload(BaseModel): | |
""" | |
Represents the payload for a message. | |
""" | |
msg_id: int # Unique identifier for the message. | |
msg_name: str # Name or description of the message. | |
class RecommendationRequest(BaseModel): | |
""" | |
Defines the structure for a recommendation request. | |
""" | |
user_id: Optional[str] = None # Optional unique identifier for the user making the request. | |
query: str = Field(..., description="The search query or input text for which recommendations are sought.") | |
k: Optional[int] = Field(default=DEFAULT_K, description=f"The number of recommendations to return, defaults to {DEFAULT_K}.") | |
class UserItemRecommendationRequest(BaseModel): | |
""" | |
Defines the structure for an item-based recommendation request. | |
""" | |
id: str = Field(..., description="The item ID (msid) to get recommendations for.") | |
user_id: Optional[str] = Field(None, description="Optional user ID. If not provided, an anonymous ID will be generated.") | |
k: Optional[int] = Field(default=DEFAULT_K, description=f"Number of recommendations to return, defaults to {DEFAULT_K}.") | |
class RetrievedDocument(BaseModel): | |
""" | |
Represents a single document retrieved as part of a recommendation. | |
""" | |
id: str # Unique identifier for the retrieved document (msid, typically a string). | |
hl: str # Headline of the document. | |
synopsis: Optional[str] = None # Synopsis or main content of the document. | |
keywords: Optional[str] = None # Keywords associated with the document. | |
type: Optional[str] = None # Optional type or category of the document. | |
taxonomy: Optional[List[str]] = None # List of taxonomy terms. | |
score: Optional[float] = None # Relevance score of the document. | |
seolocation: Optional[str] = None # Optional SEO location or URL. | |
dl: Optional[str] = None # Optional deeplink. | |
lu: Optional[str] = None # Optional last updated timestamp or string. | |
imageid: Optional[str] = None # Optional image identifier. | |
imgratio: Optional[str] = None # Optional image ratio (e.g., "16:9"). | |
imgsize: Optional[str] = None # Optional image size (e.g., "1024x768"). | |
# summary and smart_tip fields removed as they should only be in summary endpoint response | |
# Create a new model for documents with summary and smart tip | |
class RetrievedDocumentWithSummary(RetrievedDocument): | |
""" | |
Represents a document retrieved as part of a recommendation with additional summary and smart tip fields. | |
""" | |
summary: Optional[str] = "" # Generated summary of the article, defaults to empty string | |
smart_tip: Optional[Any] = None # Smart tip with related articles and summaries. | |
class SmartTipSuggestion(BaseModel): | |
label: str | |
url: str | |
# summary: Optional[str] = "" # Removed as per request | |
class SmartTip(BaseModel): | |
title: str | |
description: str | |
suggestions: List[SmartTipSuggestion] = Field(default_factory=list) | |
class PastFeedbackItem(BaseModel): | |
srcMsid: Optional[str] = "" | |
clickedMsid: Optional[str] = "" | |
resultMsids: List[str] = Field(default_factory=list) | |
# timestamp: Optional[datetime] = None # Optional: if you want to include timestamp | |
class RecommendationResponse(BaseModel): | |
""" | |
Defines the structure for a recommendation response. | |
""" | |
msid: Optional[str] = None # Made optional to handle cases where it might not be set (e.g. query-based recs) | |
retrieved_documents: List[RetrievedDocument] = Field(default_factory=list) # Use RetrievedDocument | |
generated_response: Optional[str] = None # Added to match recommender output | |
clicked_msid: Optional[Union[str, List[Any]]] = None # To match existing logic in routes.py | |
past_feedback: List[PastFeedbackItem] = Field(default_factory=list) | |
def ensure_smart_tip_format(cls, v): | |
if isinstance(v, dict) and 'smart_tip' in v and isinstance(v['smart_tip'], str): # Compatibility if old format string is somehow passed | |
v['smart_tip'] = None # Or convert to new format if possible, for now, nullify | |
return v | |
# ...other fields if present... | |
class OutputData(BaseModel): | |
""" | |
Represents a single data item in the output, often a simplified version of a retrieved document. | |
""" | |
id: str # Unique identifier for the output data item (msid, typically a string). | |
headline: Optional[str] = None # Optional headline or title for the data item. | |
type: Optional[str] = None # Optional type or category of the data item. | |
class OutputResponse(BaseModel): | |
""" | |
Defines the structure for a generic output response containing a list of data items. | |
""" | |
data: List[OutputData] # A list of output data items. | |
class FeedbackRecommendationRequest(BaseModel): | |
user_id: str | |
msid: str | |
clicked_msid: Optional[str] = None | |
k: Optional[int] = 5 | |
# Refine RetrievedDocument.smart_tip type | |
RetrievedDocument.model_fields['smart_tip'] = Field(default=None, description="Smart tip with related articles and summaries.") | |
RetrievedDocument.model_rebuild(force=True) | |
# Update the RecommendationResponse model to use RetrievedDocumentWithSummary for summary endpoint | |
class RecommendationResponseWithSummary(BaseModel): | |
""" | |
Defines the structure for a recommendation response with summaries and smart tips. | |
""" | |
msid: Optional[str] = None # Made optional to handle cases where it might not be set (e.g. query-based recs) | |
retrieved_documents: List[RetrievedDocumentWithSummary] = Field(default_factory=list) | |
generated_response: Optional[str] = None # Added to match recommender output | |
clicked_msid: Optional[Union[str, List[Any]]] = None # To match existing logic in routes.py | |
past_feedback: List[PastFeedbackItem] = Field(default_factory=list) | |
def ensure_smart_tip_format(cls, v): | |
if isinstance(v, dict) and 'smart_tip' in v and isinstance(v['smart_tip'], str): # Compatibility if old format string is somehow passed | |
v['smart_tip'] = None # Or convert to new format if possible, for now, nullify | |
return v |