# O2Sound API Documentation ## 목차 1. [개요](#개요) 2. [인증](#인증) 3. [API 엔드포인트](#api-엔드포인트) - [기본 엔드포인트](#기본-엔드포인트) - [인증 API](#인증-api) - [소셜 로그인 API](#소셜-로그인-api) - [사용자 API](#사용자-api) - [비디오 스트리밍 API](#비디오-스트리밍-api) - [영상 제작 API](#영상-제작-api) 4. [에러 처리](#에러-처리) 5. [워크플로우 상세](#워크플로우-상세) ## 개요 ### 기본 정보 - **Base URL**: `http://localhost:8000` - **API Version**: v1 - **Framework**: FastAPI - **Documentation**: `/docs` (Swagger UI), `/redoc` (ReDoc) ### 기술 스택 - **백엔드 프레임워크**: FastAPI - **비동기 작업 처리**: Celery - **메시지 브로커**: Redis - **데이터베이스**: PostgreSQL (추정) - **인증**: Session-based + OAuth 2.0 (Google) ### 응답 형식 모든 API 응답은 `@response_wrapper` 데코레이터를 통해 일관된 형식으로 반환됩니다. ## 인증 ### 세션 기반 인증 - 로그인 후 세션 쿠키를 통한 인증 - SessionMiddleware 사용 ### OAuth 2.0 - Google OAuth 지원 - 임시 토큰을 통한 안전한 토큰 교환 ## API 엔드포인트 ### 기본 엔드포인트 #### 서비스 정보 확인 ```http GET / ``` **응답 예시:** ```json { "message": "FastAPI DDD with Celery Workers", "version": "1.0.0", "docs": "/docs" } ``` #### 헬스 체크 ```http GET /health ``` **응답 예시:** ```json { "status": "healthy", "database": "connected", "redis": "connected", "celery": "running" } ``` ### 인증 API #### 회원가입 ```http POST /auth/join Content-Type: application/json ``` **요청 본문:** ```json { "user_id": "testuser", "name": "홍길동", "password": "securepassword123", "email": "test@example.com", "phone_number": "010-1234-5678" } ``` **응답 (201 Created):** ```json { "id": "123e4567-e89b-12d3-a456-426614174000", "name": "홍길동" } ``` #### 로그인 ```http POST /auth/login Content-Type: application/json ``` **요청 본문:** ```json { "user_id": "testuser", "password": "securepassword123" } ``` **응답 (200 OK):** ```json { "id": "123e4567-e89b-12d3-a456-426614174000", "name": "홍길동" } ``` ### 소셜 로그인 API #### Google OAuth 로그인 시작 ```http GET /social/google/login?return_url=http://localhost:3300/dashboard ``` **쿼리 파라미터:** - `return_url` (선택): 로그인 성공 후 리다이렉트할 URL **응답:** - Google OAuth 인증 페이지로 302 리다이렉트 #### Google OAuth 콜백 ```http GET /social/google/callback?code=AUTHORIZATION_CODE&state=STATE ``` **쿼리 파라미터:** - `code`: Google에서 제공한 인증 코드 - `state`: CSRF 방지를 위한 상태 값 - `error` (선택): OAuth 에러 발생 시 **응답:** - 성공: `{return_url}?token={temp_token_id}&auth_success=true`로 리다이렉트 - 실패: `http://localhost:3300/auth/error?error={error_message}`로 리다이렉트 #### Google 토큰 정보 조회 ```http GET /social/google/token/{temp_token_id} ``` **경로 파라미터:** - `temp_token_id`: 임시 토큰 ID **응답 (200 OK):** ```json { "access_token": "ya29.a0AfH6SMBx...", "refresh_token": "1//0gVO1VQ...", "token_type": "Bearer", "expires_in": 3599, "user_info": { "id": "google_user_id", "email": "user@gmail.com", "name": "사용자 이름", "picture": "https://lh3.googleusercontent.com/..." } } ``` ### 사용자 API #### 사용자 업체 목록 조회 ```http POST /user/items Content-Type: application/json ``` **요청 본문:** ```json { "id": "123e4567-e89b-12d3-a456-426614174000" } ``` **응답 (200 OK):** ```json { "total_count": 2, "items": [ { "item_id": "550e8400-e29b-41d4-a716-446655440000", "name": "카페 블루문", "address": "서울시 강남구 역삼동 123-45", "url": "https://bluemoon.cafe", "phone_number": "02-1234-5678", "thumbnail_url": "https://example.com/thumb1.jpg", "hashtags": ["카페", "브런치", "디저트"] } ] } ``` #### 업체 정보 수정 ```http PUT /user/item/update Content-Type: application/json ``` **요청 본문:** ```json { "id": "123e4567-e89b-12d3-a456-426614174000", "item_id": "550e8400-e29b-41d4-a716-446655440000", "name": "카페 블루문 강남점", "address": "서울시 강남구 역삼동 123-45", "url": "https://bluemoon-gangnam.cafe", "phone_number": "02-1234-5678", "thumbnail_url": "https://example.com/new-thumb.jpg" } ``` **응답 (200 OK):** ```json { "success": true, "item_id": "550e8400-e29b-41d4-a716-446655440000" } ``` #### 업체 삭제 ```http DELETE /user/item/delete Content-Type: application/json ``` **요청 본문:** ```json { "id": "123e4567-e89b-12d3-a456-426614174000", "item_id": "550e8400-e29b-41d4-a716-446655440000" } ``` **응답 (200 OK):** ```json { "success": true, "item_id": "550e8400-e29b-41d4-a716-446655440000" } ``` #### 사용자 비디오 목록 조회 ```http POST /user/videos Content-Type: application/json ``` **요청 본문:** ```json { "id": "123e4567-e89b-12d3-a456-426614174000" } ``` **응답 (200 OK):** ```json { "total_count": 3, "videos": [ { "id": "660e8400-e29b-41d4-a716-446655440000", "title": "카페 블루문 홍보 영상", "description": "아늑한 분위기의 카페 블루문을 소개합니다", "url": "/user/video/bluemoon_promo_2024.mp4", "is_uploaded": true, "download_count": 15, "resolution": "1920x1080", "status": "completed", "thumbnail_url": "https://example.com/video-thumb1.jpg" } ] } ``` #### 비디오 삭제 ```http DELETE /user/video/delete Content-Type: application/json ``` **요청 본문:** ```json { "user_id": "testuser", "video_id": "660e8400-e29b-41d4-a716-446655440000" } ``` **응답 (200 OK):** ```json { "message": "비디오가 성공적으로 삭제되었습니다" } ``` #### 사용자 프로필 조회 ```http POST /user/profile Content-Type: application/json ``` **요청 본문:** ```json { "id": "123e4567-e89b-12d3-a456-426614174000" } ``` **응답 (200 OK):** ```json { "id": "123e4567-e89b-12d3-a456-426614174000", "name": "홍길동", "email": "test@example.com", "phone_number": "010-1234-5678", "created_at": "2024-01-15T10:30:00Z" } ``` #### 프로필 수정 ```http PUT /user/profile/update Content-Type: application/json ``` **요청 본문:** ```json { "id": "123e4567-e89b-12d3-a456-426614174000", "name": "홍길동", "email": "newemail@example.com", "phone_number": "010-9876-5432" } ``` **응답 (200 OK):** ```json { "user_id": "testuser", "name": "홍길동" } ``` ### 비디오 스트리밍 API #### 비디오 파일 스트리밍 ```http GET /user/video/{filename} ``` **경로 파라미터:** - `filename`: 비디오 파일명 (URL 인코딩 지원) **예시:** ```http GET /user/video/bluemoon_promo_2024.mp4 ``` **응답:** - Content-Type: `video/mp4` - 비디오 파일 스트리밍 **에러 응답 (404 Not Found):** ```json { "detail": "Video not found" } ``` ### 영상 제작 API #### 영상 제작 워크플로우 시작 ```http POST /moviemaker/start-workflow Content-Type: application/json ``` **요청 본문:** ```json { "url": "https://bluemoon.cafe" } ``` **응답 (200 OK):** ```json { "task_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "progress": { "metadata": false, "lyrics": false, "songs": false, "images": false, "movies": false, "combined": false } } ``` #### 워크플로우 진행률 확인 ```http POST /moviemaker/progress Content-Type: application/json ``` **요청 본문:** ```json { "task_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479" } ``` **응답 (200 OK):** ```json { "progress": { "metadata": true, "lyrics": true, "songs": true, "images": false, "movies": false, "combined": false } } ``` ## 에러 처리 ### 표준 에러 응답 형식 ```json { "error_code": "ERROR_CODE", "error_message": "사용자 친화적인 에러 메시지" } ``` ### 일반적인 HTTP 상태 코드 - `200 OK`: 요청 성공 - `201 Created`: 리소스 생성 성공 - `400 Bad Request`: 잘못된 요청 - `401 Unauthorized`: 인증 필요 - `403 Forbidden`: 권한 없음 - `404 Not Found`: 리소스를 찾을 수 없음 - `422 Unprocessable Entity`: 유효성 검사 실패 - `500 Internal Server Error`: 서버 오류 ### 에러 코드 예시 - `AUTH_001`: 잘못된 로그인 정보 - `AUTH_002`: 이미 존재하는 사용자 ID - `USER_001`: 사용자를 찾을 수 없음 - `VIDEO_001`: 비디오를 찾을 수 없음 - `TASK_001`: 작업을 찾을 수 없음 ## 워크플로우 상세 ### 영상 제작 프로세스 1. **URL 크롤링 (task1_crawl)** - 입력 URL에서 메타데이터 추출 - 업체명, 설명, 키워드 등 수집 2. **병렬 처리** **가사 및 음악 생성 브랜치:** - **가사 생성 (task2_generate_lyrics)** - 크롤링한 메타데이터 기반 가사 생성 - AI 모델을 통한 창의적인 가사 작성 - **음악 생성 (task3_generate_music)** - 생성된 가사에 맞는 음악 제작 - 장르, 템포, 분위기 자동 매칭 **이미지 및 비디오 생성 브랜치:** - **이미지 크롤링 (task1_crawl_images)** - 웹사이트에서 관련 이미지 수집 - 품질 및 관련성 필터링 - **비디오 생성 (task4_generate_video)** - 수집된 이미지로 비디오 제작 - 전환 효과 및 애니메이션 적용 3. **최종 병합 (task5_merge_results)** - 음악과 비디오 동기화 - 최종 영상 파일 생성 - 업로드 및 저장 ### 진행률 추적 - Redis를 통한 실시간 상태 업데이트 - 각 단계별 완료 상태 확인 가능 - 비동기 작업으로 긴 처리 시간 대응 ## 개발 가이드 ### 로컬 개발 환경 실행 ```bash # Poetry 환경 설정 poetry install # 환경 변수 설정 cp .env.local .env # Redis 실행 (Docker) docker run -d -p 6379:6379 redis # Celery Worker 실행 ./run-celery.sh # FastAPI 서버 실행 ./run-local.sh ``` ### API 테스트 - Swagger UI: `http://localhost:8000/docs` - ReDoc: `http://localhost:8000/redoc` ### 프로덕션 배포 ```bash # Docker 이미지 빌드 docker build -t o2sound-backend . # 프로덕션 실행 ./run-prod.sh ```