From 19bd12d5812c36c0f6923e9306b71d7707d6b2eb Mon Sep 17 00:00:00 2001 From: Dohyun Lim Date: Mon, 2 Feb 2026 10:36:42 +0900 Subject: [PATCH] add sns endpoint --- app/sns/__init__.py | 0 app/sns/api/__init__.py | 0 app/sns/api/routers/__init__.py | 0 app/sns/api/routers/v1/__init__.py | 0 app/sns/api/routers/v1/sns.py | 50 ++++++++++++++++++++++++++ app/sns/api/sns_admin.py | 0 app/sns/dependency.py | 0 app/sns/models.py | 0 app/sns/schemas/__init__.py | 0 app/sns/schemas/sns_schema.py | 42 ++++++++++++++++++++++ app/sns/services/__init__.py | 0 app/sns/services/sns.py | 0 app/sns/tests/__init__.py | 0 app/sns/tests/conftest.py | 0 app/sns/tests/sns/__init__.py | 0 app/sns/tests/sns/conftest.py | 0 app/sns/tests/sns/test_db.py | 0 app/sns/tests/test_db.py | 0 app/sns/worker/__init__.py | 0 app/sns/worker/sns_task.py | 0 plan.md => docs/plan/instagram-plan.md | 0 main.py | 15 +++++++- 22 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 app/sns/__init__.py create mode 100644 app/sns/api/__init__.py create mode 100644 app/sns/api/routers/__init__.py create mode 100644 app/sns/api/routers/v1/__init__.py create mode 100644 app/sns/api/routers/v1/sns.py create mode 100644 app/sns/api/sns_admin.py create mode 100644 app/sns/dependency.py create mode 100644 app/sns/models.py create mode 100644 app/sns/schemas/__init__.py create mode 100644 app/sns/schemas/sns_schema.py create mode 100644 app/sns/services/__init__.py create mode 100644 app/sns/services/sns.py create mode 100644 app/sns/tests/__init__.py create mode 100644 app/sns/tests/conftest.py create mode 100644 app/sns/tests/sns/__init__.py create mode 100644 app/sns/tests/sns/conftest.py create mode 100644 app/sns/tests/sns/test_db.py create mode 100644 app/sns/tests/test_db.py create mode 100644 app/sns/worker/__init__.py create mode 100644 app/sns/worker/sns_task.py rename plan.md => docs/plan/instagram-plan.md (100%) diff --git a/app/sns/__init__.py b/app/sns/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/api/__init__.py b/app/sns/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/api/routers/__init__.py b/app/sns/api/routers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/api/routers/v1/__init__.py b/app/sns/api/routers/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/api/routers/v1/sns.py b/app/sns/api/routers/v1/sns.py new file mode 100644 index 0000000..eefb686 --- /dev/null +++ b/app/sns/api/routers/v1/sns.py @@ -0,0 +1,50 @@ +""" +SNS API 라우터 + +Instagram 업로드 관련 엔드포인트를 제공합니다. +""" + +from fastapi import APIRouter + +from app.sns.schemas.sns_schema import InstagramUploadResponse +from app.utils.logger import get_logger + +logger = get_logger(__name__) + +router = APIRouter(prefix="/sns", tags=["SNS"]) + + +@router.get( + "/instagram/upload/{task_id}", + summary="Instagram 업로드 상태 조회", + description=""" +## 개요 +task_id에 해당하는 Instagram 업로드 작업의 상태를 조회합니다. + +## 경로 파라미터 +- **task_id**: 업로드 작업 고유 식별자 + +## 반환 정보 +- **task_id**: 작업 고유 식별자 +- **state**: 업로드 상태 (pending, processing, completed, failed) +- **message**: 상태 메시지 +- **error**: 에러 메시지 (실패 시, 기본값: null) + """, + response_model=InstagramUploadResponse, + responses={ + 200: {"description": "상태 조회 성공"}, + }, +) +async def get_instagram_upload_status(task_id: str) -> InstagramUploadResponse: + """Instagram 업로드 작업의 상태를 반환합니다.""" + logger.info(f"[get_instagram_upload_status] START - task_id: {task_id}") + + response = InstagramUploadResponse( + task_id=task_id, + state="pending", + message="업로드 대기 중입니다.", + error=None, + ) + + logger.info(f"[get_instagram_upload_status] SUCCESS - task_id: {task_id}, state: {response.state}") + return response diff --git a/app/sns/api/sns_admin.py b/app/sns/api/sns_admin.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/dependency.py b/app/sns/dependency.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/models.py b/app/sns/models.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/schemas/__init__.py b/app/sns/schemas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/schemas/sns_schema.py b/app/sns/schemas/sns_schema.py new file mode 100644 index 0000000..017a21c --- /dev/null +++ b/app/sns/schemas/sns_schema.py @@ -0,0 +1,42 @@ +""" +SNS API Schemas + +Instagram 업로드 관련 Pydantic 스키마를 정의합니다. +""" + +from typing import Optional + +from pydantic import BaseModel, ConfigDict, Field + + +class InstagramUploadResponse(BaseModel): + """Instagram 업로드 상태 응답 스키마 + + Usage: + GET /sns/instagram/upload/{task_id} + Instagram 업로드 작업의 상태를 반환합니다. + + Example Response: + { + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "state": "pending", + "message": "업로드 대기 중입니다.", + "error": null + } + """ + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "state": "pending", + "message": "업로드 대기 중입니다.", + "error": None, + } + } + ) + + task_id: str = Field(..., description="작업 고유 식별자") + state: str = Field(..., description="업로드 상태 (pending, processing, completed, failed)") + message: str = Field(..., description="상태 메시지") + error: Optional[str] = Field(default=None, description="에러 메시지 (실패 시)") diff --git a/app/sns/services/__init__.py b/app/sns/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/services/sns.py b/app/sns/services/sns.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/tests/__init__.py b/app/sns/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/tests/conftest.py b/app/sns/tests/conftest.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/tests/sns/__init__.py b/app/sns/tests/sns/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/tests/sns/conftest.py b/app/sns/tests/sns/conftest.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/tests/sns/test_db.py b/app/sns/tests/sns/test_db.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/tests/test_db.py b/app/sns/tests/test_db.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/worker/__init__.py b/app/sns/worker/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/sns/worker/sns_task.py b/app/sns/worker/sns_task.py new file mode 100644 index 0000000..e69de29 diff --git a/plan.md b/docs/plan/instagram-plan.md similarity index 100% rename from plan.md rename to docs/plan/instagram-plan.md diff --git a/main.py b/main.py index 43763a7..a36a9b0 100644 --- a/main.py +++ b/main.py @@ -16,6 +16,7 @@ from app.home.api.routers.v1.home import router as home_router from app.user.api.routers.v1.auth import router as auth_router, test_router as auth_test_router from app.lyric.api.routers.v1.lyric import router as lyric_router from app.song.api.routers.v1.song import router as song_router +from app.sns.api.routers.v1.sns import router as sns_router from app.video.api.routers.v1.video import router as video_router from app.utils.cors import CustomCORSMiddleware from config import prj_settings @@ -151,6 +152,17 @@ tags_metadata = [ - created_at 기준 내림차순 정렬됩니다. - 삭제는 소프트 삭제(is_deleted=True) 방식으로 처리되며, 데이터 복구가 가능합니다. - 삭제 대상: Video, SongTimestamp, Song, Lyric, Image, Project +""", + }, + { + "name": "SNS", + "description": """SNS 업로드 API - Instagram Graph API + +**인증: 필요** - `Authorization: Bearer {access_token}` 헤더 필수 + +## 주요 기능 + +- `GET /sns/instagram/upload/{task_id}` - Instagram 업로드 상태 조회 """, }, ] @@ -226,7 +238,7 @@ def custom_openapi(): if method in ["get", "post", "put", "patch", "delete"]: # 공개 엔드포인트가 아닌 경우 인증 필요 is_public = any(public_path in path for public_path in public_endpoints) - if not is_public and path.startswith("/api/"): + if not is_public: operation["security"] = [{"BearerAuth": []}] app.openapi_schema = openapi_schema @@ -267,6 +279,7 @@ app.include_router(lyric_router) app.include_router(song_router) app.include_router(video_router) app.include_router(archive_router) # Archive API 라우터 추가 +app.include_router(sns_router) # SNS API 라우터 추가 # DEBUG 모드에서만 테스트 라우터 등록 if prj_settings.DEBUG: