144 lines
3.4 KiB
Python
144 lines
3.4 KiB
Python
from datetime import datetime
|
|
from typing import List, Optional
|
|
|
|
from pydantic import BaseModel, EmailStr, field_validator
|
|
|
|
|
|
class RegisterRequest(BaseModel):
|
|
email: EmailStr
|
|
password: str
|
|
|
|
@field_validator("password")
|
|
@classmethod
|
|
def password_min_length(cls, v: str) -> str:
|
|
if len(v) < 8:
|
|
raise ValueError("Password must be at least 8 characters")
|
|
return v
|
|
|
|
|
|
class LoginRequest(BaseModel):
|
|
email: EmailStr
|
|
password: str
|
|
|
|
|
|
class UserResponse(BaseModel):
|
|
id: str
|
|
email: str
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class AssetResponse(BaseModel):
|
|
id: str
|
|
asset_type: str
|
|
mime_type: str
|
|
original_filename: str
|
|
storage_path: str
|
|
size_bytes: int
|
|
width: Optional[int] = None
|
|
height: Optional[int] = None
|
|
duration_seconds: Optional[float] = None
|
|
thumbnail_path: Optional[str] = None
|
|
is_trashed: bool = False
|
|
delete_after_at: Optional[datetime] = None
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class JobCreateRequest(BaseModel):
|
|
mode: str
|
|
submode: Optional[str] = None
|
|
prompt: str
|
|
negative_prompt: Optional[str] = None
|
|
ground_truth_asset_id: str
|
|
motion_asset_id: Optional[str] = None
|
|
audio_asset_id: Optional[str] = None
|
|
reference_asset_ids: Optional[List[str]] = None
|
|
pose_asset_id: Optional[str] = None
|
|
settings: Optional[dict] = None
|
|
|
|
@field_validator("mode")
|
|
@classmethod
|
|
def validate_mode(cls, v: str) -> str:
|
|
if v not in ("animate", "audio"):
|
|
raise ValueError("mode must be 'animate' or 'audio'")
|
|
return v
|
|
|
|
@field_validator("submode")
|
|
@classmethod
|
|
def validate_submode(cls, v: Optional[str]) -> Optional[str]:
|
|
if v is not None and v not in ("move", "mix"):
|
|
raise ValueError("submode must be 'move' or 'mix'")
|
|
return v
|
|
|
|
|
|
class JobOutputResponse(BaseModel):
|
|
id: str
|
|
output_type: str
|
|
file_path: str
|
|
poster_path: Optional[str] = None
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class JobEventResponse(BaseModel):
|
|
id: str
|
|
event_type: str
|
|
message: Optional[str] = None
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class AssetTrashRequest(BaseModel):
|
|
asset_ids: List[str]
|
|
|
|
|
|
class JobResponse(BaseModel):
|
|
id: str
|
|
mode: str
|
|
submode: Optional[str] = None
|
|
prompt: str
|
|
negative_prompt: Optional[str] = None
|
|
status: str
|
|
comfy_prompt_id: Optional[str] = None
|
|
workflow_template_name: Optional[str] = None
|
|
error_message: Optional[str] = None
|
|
ground_truth_asset_id: Optional[str] = None
|
|
motion_asset_id: Optional[str] = None
|
|
audio_asset_id: Optional[str] = None
|
|
pose_asset_id: Optional[str] = None
|
|
outputs: List[JobOutputResponse] = []
|
|
events: List[JobEventResponse] = []
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class JobListResponse(BaseModel):
|
|
id: str
|
|
mode: str
|
|
submode: Optional[str] = None
|
|
prompt: str
|
|
error_message: Optional[str] = None
|
|
status: str
|
|
ground_truth_asset_id: Optional[str] = None
|
|
motion_asset_id: Optional[str] = None
|
|
audio_asset_id: Optional[str] = None
|
|
pose_asset_id: Optional[str] = None
|
|
outputs: List[JobOutputResponse] = []
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|