O2Sound_ver2_final/backend/docs/API_Documentation.md

541 lines
10 KiB
Markdown

# 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
```