from __future__ import annotations from dataclasses import dataclass, field from datetime import datetime, timezone from typing import Any from uuid import uuid4 @dataclass(slots=True) class GeneratedVideo: id: str workspace_id: str project_id: str generation_task_id: str name: str file_url: str file_size: int duration: float width: int height: int fps: float thumbnail_url: str | None = None status: str = "completed" review_status: str = "pending_review" generation_params: dict[str, Any] = field(default_factory=dict) generated_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc)) created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc)) @classmethod def create( cls, workspace_id: str, project_id: str, generation_task_id: str, name: str, file_url: str, *, file_size: int, duration: float, width: int, height: int, fps: float, thumbnail_url: str | None = None, generation_params: dict[str, Any] | None = None, ) -> "GeneratedVideo": if not workspace_id.strip(): raise ValueError("workspace_id 不能为空") if not project_id.strip(): raise ValueError("project_id 不能为空") if not generation_task_id.strip(): raise ValueError("generation_task_id 不能为空") if not name.strip(): raise ValueError("name 不能为空") if not file_url.strip(): raise ValueError("file_url 不能为空") return cls( id=uuid4().hex, workspace_id=workspace_id.strip(), project_id=project_id.strip(), generation_task_id=generation_task_id.strip(), name=name.strip(), file_url=file_url.strip(), file_size=file_size, duration=duration, width=width, height=height, fps=fps, thumbnail_url=thumbnail_url, generation_params=generation_params or {}, )