Spaces:
Running
Running
| """Data models and schemas for the application.""" | |
| from pydantic import BaseModel, Field, EmailStr, validator | |
| from typing import Optional | |
| from datetime import datetime | |
| # ===== USER SCHEMAS ===== | |
| class UserCreate(BaseModel): | |
| """What we need to create a user.""" | |
| email: EmailStr | |
| name: str = Field(..., min_length=1, max_length=100) | |
| password: str = Field(..., min_length=8) | |
| class UserLogin(BaseModel): | |
| """What we need to login.""" | |
| email: EmailStr | |
| password: str | |
| class UserResponse(BaseModel): | |
| """What we return about a user.""" | |
| id: int | |
| email: str | |
| name: str | |
| created_at: datetime | |
| class Config: | |
| from_attributes = True | |
| class UserUpdate(BaseModel): | |
| """What can be updated.""" | |
| name: Optional[str] = Field(None, min_length=1, max_length=100) | |
| # ===== AUTH SCHEMAS ===== | |
| class Token(BaseModel): | |
| """JWT token response.""" | |
| access_token: str | |
| token_type: str = "bearer" | |
| class TokenData(BaseModel): | |
| """Data encoded in the token.""" | |
| user_id: int | |
| email: str | |
| # ===== CHAT SCHEMAS ===== | |
| class Message(BaseModel): | |
| """A chat message.""" | |
| id: Optional[int] = None | |
| conversation_id: int | |
| sender_id: int | |
| content: str | |
| created_at: Optional[datetime] = None | |
| class Conversation(BaseModel): | |
| """A conversation thread.""" | |
| id: Optional[int] = None | |
| user_id: int | |
| title: str | |
| created_at: Optional[datetime] = None | |
| # ===== AI QUERY SCHEMAS ===== | |
| class QueryRequest(BaseModel): | |
| """Request for AI query.""" | |
| conversation_id: Optional[str] = Field( | |
| default=None, | |
| max_length=128, | |
| description="Optional conversation/session id used for chat memory and per-thread RAG" | |
| ) | |
| query: str = Field( | |
| ..., | |
| min_length=1, | |
| max_length=1000, | |
| description="The question or prompt to send to the AI" | |
| ) | |
| def validate_query(cls, v): | |
| if not v.strip(): | |
| raise ValueError("Query cannot be empty") | |
| # Basic sanitization - remove potential script tags | |
| v = v.replace("<script", "").replace("</script>", "") | |
| return v.strip() | |
| def validate_conversation_id(cls, v): | |
| if v is None: | |
| return None | |
| v = str(v).strip() | |
| return v or None | |
| class QueryResponse(BaseModel): | |
| """Response from AI query.""" | |
| success: bool | |
| response: Optional[str] = None | |
| error: Optional[str] = None | |
| timestamp: datetime = Field(default_factory=datetime.utcnow) | |
| requires_auth: bool = False # True if Google authentication is needed | |
| auth_url: Optional[str] = None # Google OAuth URL if authentication is required | |
| class HealthCheckResponse(BaseModel): | |
| """Health check response.""" | |
| status: str # "healthy", "degraded", "unhealthy" | |
| timestamp: datetime = Field(default_factory=datetime.utcnow) | |
| version: str = "1.0.0" | |
| components: dict = {} | |
| # ===== CONVERSATION MANAGEMENT SCHEMAS ===== | |
| class MessageResponse(BaseModel): | |
| """Response format for a single message.""" | |
| id: int | |
| sender_id: int | |
| content: str | |
| created_at: datetime | |
| class Config: | |
| from_attributes = True | |
| class ConversationListResponse(BaseModel): | |
| """Brief conversation info for listing.""" | |
| id: int | |
| title: Optional[str] = None | |
| created_at: datetime | |
| last_message_at: datetime | |
| message_count: int | |
| class Config: | |
| from_attributes = True | |
| class ConversationDetailResponse(BaseModel): | |
| """Full conversation with all messages.""" | |
| id: int | |
| title: Optional[str] = None | |
| created_at: datetime | |
| last_message_at: datetime | |
| messages: list[MessageResponse] | |
| class Config: | |
| from_attributes = True | |
| class ChatRequest(BaseModel): | |
| """Chat message request.""" | |
| conversation_id: Optional[int] = Field( | |
| None, | |
| description="Existing conversation ID, or None to create new conversation" | |
| ) | |
| query: str = Field( | |
| ..., | |
| min_length=1, | |
| max_length=2000, | |
| description="User's message or query" | |
| ) | |
| def validate_query(cls, v): | |
| if not v.strip(): | |
| raise ValueError("Query cannot be empty") | |
| return v.strip() | |
| class ChatResponse(BaseModel): | |
| """Chat message response.""" | |
| conversation_id: int | |
| response: str | |
| timestamp: datetime = Field(default_factory=datetime.utcnow) | |
| class Config: | |
| from_attributes = True | |
| class PaginatedConversationsResponse(BaseModel): | |
| """Paginated list of conversations.""" | |
| conversations: list[ConversationListResponse] | |
| total: int | |
| skip: int | |
| limit: int | |
| class Config: | |
| from_attributes = True |