o2o-castad-backend/app/sns/schemas/sns_schema.py

135 lines
3.6 KiB
Python

"""
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