from __future__ import annotations from typing import Optional from pydantic import BaseModel, Field, field_validator from app.config import settings # --- Request --- class GenerateForm(BaseModel): prompt: Optional[str] = Field(None, max_length=1000) width: int = Field(768, ge=256, le=2048, multiple_of=32) height: int = Field(512, ge=256, le=2048, multiple_of=32) num_frames: int = Field(65, ge=9, le=settings.max_frame_count) fps: float = Field(24.0, gt=0, le=60) seed: Optional[int] = Field(None) model_config = {"extra": "forbid"} @field_validator("num_frames") @classmethod def check_frames(cls, v: int) -> int: if v % 8 != 1: n = v // 8 candidates = sorted( 8 * i + 1 for i in range(max(1, n - 2), n + 3) if 8 * i + 1 <= settings.max_frame_count ) raise ValueError(f"num_frames must be 8n+1. Got {v}. Closest valid: {candidates}") return v # --- Job Status --- class JobStatusResponse(BaseModel): job_id: str status: str # pending, processing, completed, failed prompt: Optional[str] = None params: Optional[dict] = None error: Optional[str] = None created_at: Optional[str] = None completed_at: Optional[str] = None # --- Submission Response --- class JobSubmitResponse(BaseModel): job_id: str status: str = "pending" message: str = "Job submitted. Poll GET /jobs/{job_id} for status." # --- Error --- class ErrorResponse(BaseModel): error: str