Spaces:
Runtime error
Runtime error
File size: 3,339 Bytes
a5ddf46 9f77adc a5ddf46 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | """
Pydantic models for the Personalization API endpoint.
These models define the request/response structure for the POST /api/personalize endpoint.
"""
from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime
class PersonalizeRequest(BaseModel):
"""
Request body for POST /api/personalize endpoint.
"""
chapter_id: str = Field(
...,
description="Unique identifier for the chapter",
min_length=1
)
chapter_content: str = Field(
...,
description="Full markdown content to personalize",
min_length=1,
max_length=50000
)
user_id: Optional[str] = Field(
None,
description="User ID from frontend (for auth bypass in local testing)"
)
class HardwareContext(BaseModel):
"""
Hardware context included in personalization summary.
"""
system_capability: str
operating_system: str
class PersonalizationSummary(BaseModel):
"""
Summary of personalization adjustments made.
"""
experience_level: str
programming_context: List[str]
hardware_context: HardwareContext
adjustments_made: List[str]
class PersonalizeSuccessResponse(BaseModel):
"""
Success response from POST /api/personalize endpoint.
"""
success: bool = True
personalized_content: str
chapter_id: str
personalization_summary: PersonalizationSummary
timestamp: str
class PersonalizeErrorResponse(BaseModel):
"""
Error response from POST /api/personalize endpoint.
"""
success: bool = False
error: str
message: str
missing_fields: Optional[List[str]] = None
retry_after: Optional[int] = None
field: Optional[str] = None
class UserProfile(BaseModel):
"""
User profile data used for personalization.
Maps to the user_profiles table in the database.
"""
auth_user_id: str
experience_level: str # beginner, intermediate, advanced, expert
programming_languages: List[str]
frameworks_platforms: List[str]
device_type: str # desktop, laptop, tablet, mobile, embedded
operating_system: str # windows, macos, linux, other
system_capability: str # low, medium, high
def is_complete(self) -> tuple[bool, List[str]]:
"""
Check if all required fields are present for personalization.
Returns:
Tuple of (is_valid, list_of_missing_fields)
"""
missing = []
if not self.experience_level:
missing.append("experience_level")
if not self.programming_languages:
missing.append("programming_languages")
if not self.frameworks_platforms:
missing.append("frameworks_platforms")
if not self.device_type:
missing.append("device_type")
if not self.operating_system:
missing.append("operating_system")
if not self.system_capability:
missing.append("system_capability")
return (len(missing) == 0, missing)
# Error code constants
class ErrorCodes:
AUTH_REQUIRED = "AUTH_REQUIRED"
PROFILE_NOT_FOUND = "PROFILE_NOT_FOUND"
PROFILE_INCOMPLETE = "PROFILE_INCOMPLETE"
INVALID_REQUEST = "INVALID_REQUEST"
RATE_LIMITED = "RATE_LIMITED"
PERSONALIZATION_FAILED = "PERSONALIZATION_FAILED"
|