from __future__ import annotations import sys from dataclasses import dataclass, field from datetime import datetime, timezone if sys.version_info >= (3, 11): from enum import StrEnum else: from enum import Enum class StrEnum(str, Enum): pass from uuid import uuid4 class AssetLibraryKind(StrEnum): VIDEO = "video" VOICE = "voice" IMAGE = "image" class IngestJobStatus(StrEnum): PENDING = "pending" PROCESSING = "processing" COMPLETED = "completed" FAILED = "failed" class ClassificationJobStatus(StrEnum): PENDING = "pending" PROCESSING = "processing" COMPLETED = "completed" FAILED = "failed" @classmethod def _missing_(cls, value: object) -> "ClassificationJobStatus": """兼容历史数据,避免枚举转换失败导致500。 - done → COMPLETED(早期版本用 done 表示完成) - 其他未知值 → PENDING(兜底,不阻塞业务) """ if isinstance(value, str): normalized = value.strip().lower() if normalized in ("done", "success", "finished", "complete"): return cls.COMPLETED if normalized in ("fail", "error", "err"): return cls.FAILED if normalized in ("process", "processing", "running", "run"): return cls.PROCESSING return cls.PENDING # 向后兼容别名 ClassificationStatus = ClassificationJobStatus class AssetClassification(StrEnum): """Asset classification categories.""" SCENIC = "scenic" # 风景 PRODUCT = "product" # 产品 PERSON = "person" # 人物 ANIMAL = "animal" # 动物 FOOD = "food" # 美食 TECH = "tech" # 科技 SPORT = "sport" # 运动 MUSIC = "music" # 音乐 OTHER = "other" # 其他 @dataclass(slots=True) class ClassificationJob: id: str project_id: str asset_id: str status: ClassificationJobStatus = ClassificationJobStatus.PENDING classification: str = "" # Result: AssetClassification value confidence: float = 0.0 # 0.0 - 1.0 error_message: str = "" created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc)) updated_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc)) @classmethod def create( cls, project_id: str, asset_id: str, ) -> "ClassificationJob": if not project_id.strip(): raise ValueError("project_id 不能为空") if not asset_id.strip(): raise ValueError("asset_id 不能为空") return cls( id=uuid4().hex, project_id=project_id.strip(), asset_id=asset_id.strip(), )