Some checks failed
Build and Push Docker Images / changes (push) Has been cancelled
Build and Push Docker Images / build-backend (push) Has been cancelled
Build and Push Docker Images / build-frontend (push) Has been cancelled
Build and Push Docker Images / build-admin-frontend (push) Has been cancelled
129 lines
3.0 KiB
Python
129 lines
3.0 KiB
Python
"""Story-related Pydantic schemas."""
|
|
|
|
from datetime import datetime
|
|
from typing import Literal
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
MAX_DATA_LENGTH = 2000
|
|
MAX_EDU_THEME_LENGTH = 200
|
|
MAX_TTS_LENGTH = 4000
|
|
|
|
|
|
class StoryStatusMixin(BaseModel):
|
|
"""Shared generation status fields returned by story APIs."""
|
|
|
|
generation_status: str
|
|
image_status: str
|
|
audio_status: str
|
|
last_error: str | None = None
|
|
|
|
|
|
class GenerateRequest(BaseModel):
|
|
"""Story generation request."""
|
|
|
|
type: Literal["keywords", "full_story"]
|
|
data: str = Field(..., min_length=1, max_length=MAX_DATA_LENGTH)
|
|
education_theme: str | None = Field(default=None, max_length=MAX_EDU_THEME_LENGTH)
|
|
child_profile_id: str | None = None
|
|
universe_id: str | None = None
|
|
|
|
|
|
class StoryResponse(StoryStatusMixin):
|
|
"""Story generation response."""
|
|
|
|
id: int
|
|
title: str
|
|
story_text: str
|
|
cover_prompt: str | None
|
|
image_url: str | None
|
|
mode: str
|
|
child_profile_id: str | None = None
|
|
universe_id: str | None = None
|
|
|
|
|
|
class StoryListItem(StoryStatusMixin):
|
|
"""Story list item."""
|
|
|
|
id: int
|
|
title: str
|
|
image_url: str | None
|
|
created_at: datetime
|
|
mode: str
|
|
|
|
|
|
class FullStoryResponse(StoryStatusMixin):
|
|
"""Full story response with asset status."""
|
|
|
|
id: int
|
|
title: str
|
|
story_text: str
|
|
cover_prompt: str | None
|
|
image_url: str | None
|
|
audio_ready: bool
|
|
mode: str
|
|
errors: dict[str, str | None] = Field(default_factory=dict)
|
|
child_profile_id: str | None = None
|
|
universe_id: str | None = None
|
|
|
|
|
|
class StorybookRequest(BaseModel):
|
|
"""Storybook generation request."""
|
|
|
|
keywords: str = Field(..., min_length=1, max_length=200)
|
|
page_count: int = Field(default=6, ge=4, le=12)
|
|
education_theme: str | None = Field(default=None, max_length=MAX_EDU_THEME_LENGTH)
|
|
generate_images: bool = Field(default=False, description="Whether to generate images too.")
|
|
child_profile_id: str | None = None
|
|
universe_id: str | None = None
|
|
|
|
|
|
class StorybookPageResponse(BaseModel):
|
|
"""One storybook page."""
|
|
|
|
page_number: int
|
|
text: str
|
|
image_prompt: str
|
|
image_url: str | None = None
|
|
|
|
|
|
class StorybookResponse(StoryStatusMixin):
|
|
"""Storybook generation response."""
|
|
|
|
id: int | None = None
|
|
title: str
|
|
main_character: str
|
|
art_style: str
|
|
pages: list[StorybookPageResponse]
|
|
cover_prompt: str
|
|
cover_url: str | None = None
|
|
|
|
|
|
class StoryDetailResponse(StoryStatusMixin):
|
|
"""Story detail response for both stories and storybooks."""
|
|
|
|
id: int
|
|
title: str
|
|
story_text: str | None = None
|
|
pages: list[StorybookPageResponse] | None = None
|
|
cover_prompt: str | None
|
|
image_url: str | None
|
|
mode: str
|
|
child_profile_id: str | None = None
|
|
universe_id: str | None = None
|
|
|
|
|
|
class StoryImageResponse(StoryStatusMixin):
|
|
"""Cover image generation response."""
|
|
|
|
image_url: str | None
|
|
|
|
|
|
class AchievementItem(BaseModel):
|
|
"""Achievement item returned for a story."""
|
|
|
|
type: str
|
|
description: str
|
|
obtained_at: str | None = None
|