from pydantic import BaseModel, Field class UploadAssetRequest(BaseModel): """素材上传请求(multipart form)""" project_id: str = Field(..., min_length=1, description="项目 ID") library_id: str = Field(..., min_length=1, description="素材库 ID") file_hash: str = Field(default="", max_length=64, description="文件 MD5 哈希,用于去重检测") class DirectUploadPrepareRequest(BaseModel): project_id: str = Field(..., min_length=1) library_id: str = Field(..., min_length=1) filename: str = Field(..., min_length=1, max_length=255) content_type: str = Field(default="application/octet-stream", min_length=1, max_length=100) file_size: int = Field(..., gt=0) file_hash: str = Field(default="", max_length=64, description="文件 MD5 哈希,用于去重检测") class DirectUploadPrepareResponse(BaseModel): upload_url: str method: str storage_key: str expires_at: str fields: dict[str, str] max_size_bytes: int class DirectUploadCompleteRequest(BaseModel): project_id: str = Field(..., min_length=1) library_id: str = Field(..., min_length=1) storage_key: str = Field(..., min_length=1, max_length=255) file_hash: str = Field(default="", max_length=64, description="文件 MD5 哈希,用于去重检测") class DirectUploadCompleteResponse(BaseModel): storage_key: str ingest_job_id: str duplicated: bool = Field(default=False, description="是否为重复素材(命中去重)") asset_id: str = Field(default="", description="重复素材的 asset_id(duplicated=true 时返回)") class UploadAssetResponse(BaseModel): storage_key: str ingest_job_id: str url: str = Field(..., description="Public URL of uploaded file") duplicated: bool = Field(default=False, description="是否为重复素材(命中去重)") asset_id: str = Field(default="", description="重复素材的 asset_id(duplicated=true 时返回)")