""" SNS API Schemas Instagram 업로드 관련 Pydantic 스키마를 정의합니다. """ from datetime import datetime from typing import Optional from pydantic import BaseModel, ConfigDict, Field class InstagramUploadRequest(BaseModel): """Instagram 업로드 요청 스키마 Usage: POST /sns/instagram/upload/{task_id} Instagram에 비디오를 업로드합니다. Example Request: { "caption": "Test video from Instagram POC #test", "share_to_feed": true } """ model_config = ConfigDict( json_schema_extra={ "example": { "caption": "Test video from Instagram POC #test", "share_to_feed": True, } } ) caption: str = Field( default="", description="게시물 캡션", max_length=2200, ) share_to_feed: bool = Field( default=True, description="피드에 공유 여부", ) class InstagramUploadResponse(BaseModel): """Instagram 업로드 응답 스키마 Usage: POST /sns/instagram/upload/{task_id} Instagram 업로드 작업의 결과를 반환합니다. Example Response (성공): { "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", "state": "completed", "message": "Instagram 업로드 완료", "media_id": "17841405822304914", "permalink": "https://www.instagram.com/p/ABC123/", "error": null } """ model_config = ConfigDict( json_schema_extra={ "example": { "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", "state": "completed", "message": "Instagram 업로드 완료", "media_id": "17841405822304914", "permalink": "https://www.instagram.com/p/ABC123/", "error": None, } } ) task_id: str = Field(..., description="작업 고유 식별자") state: str = Field(..., description="업로드 상태 (pending, processing, completed, failed)") message: str = Field(..., description="상태 메시지") media_id: Optional[str] = Field(default=None, description="Instagram 미디어 ID (성공 시)") permalink: Optional[str] = Field(default=None, description="Instagram 게시물 URL (성공 시)") error: Optional[str] = Field(default=None, description="에러 메시지 (실패 시)") class Media(BaseModel): """Instagram 미디어 정보""" id: str media_type: Optional[str] = None media_url: Optional[str] = None thumbnail_url: Optional[str] = None caption: Optional[str] = None timestamp: Optional[datetime] = None permalink: Optional[str] = None like_count: int = 0 comments_count: int = 0 children: Optional[list["Media"]] = None class MediaContainer(BaseModel): """미디어 컨테이너 상태""" id: str status_code: Optional[str] = None status: Optional[str] = None @property def is_finished(self) -> bool: return self.status_code == "FINISHED" @property def is_error(self) -> bool: return self.status_code == "ERROR" @property def is_in_progress(self) -> bool: return self.status_code == "IN_PROGRESS" class APIError(BaseModel): """API 에러 응답""" message: str type: Optional[str] = None code: Optional[int] = None error_subcode: Optional[int] = None fbtrace_id: Optional[str] = None class ErrorResponse(BaseModel): """에러 응답 래퍼""" error: APIError