""" 空镜素材 Schema ============== """ from pydantic import BaseModel, Field, field_validator class MaterialInfo(BaseModel): """素材条目""" url: str = Field(description="素材 URL(远程或本地路径)") duration: float = Field(description="素材时长(秒)") class MatchMaterialRequest(BaseModel): """匹配素材请求""" scene: str = Field(description="分镜场景描述") duration: float = Field(description="所需时长(秒)", gt=0) project_id: str | None = Field(default=None, description="项目ID,用于跨分镜去重") @field_validator("scene") @classmethod def _validate_scene(cls, v: str) -> str: v = v.strip() if not v: raise ValueError("场景描述不能为空") return v @field_validator("project_id") @classmethod def _validate_project_id(cls, v: str | None) -> str | None: if v is not None and not v.strip(): return None return v class BatchMatchSceneItem(BaseModel): """批量匹配场景项""" scene: str = Field(description="分镜场景描述") duration: float = Field(description="所需时长(秒)", gt=0) @field_validator("scene") @classmethod def _validate_scene(cls, v: str) -> str: v = v.strip() if not v: raise ValueError("场景描述不能为空") return v class BatchMatchMaterialRequest(BaseModel): """批量匹配素材请求""" project_id: str | None = Field(default=None, description="项目ID,用于跨分镜去重") scenes: list[BatchMatchSceneItem] = Field( description="分镜场景列表", min_length=1, ) @field_validator("project_id") @classmethod def _validate_project_id(cls, v: str | None) -> str | None: if v is not None and not v.strip(): return None return v class BatchMatchMaterialResponse(BaseModel): """批量匹配素材响应""" project_id: str | None = Field(description="项目ID") results: list[MaterialInfo | None] = Field(description="匹配结果列表,与 scenes 一一对应")