Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions App/schemas/auth_schema.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
from pydantic import BaseModel, EmailStr, Field

# [응답용] 프론트엔드 반환용 유저 기본 정보 (보안상 비밀번호 제외)
class UserData(BaseModel):
id: int
name: str
email: str
"""
[응답용] 프론트엔드 반환용 유저 기본 정보 (보안상 비밀번호 제외)
"""
id: int = Field(..., description="유저 고유 ID")
name: str = Field(..., description="유저 이름")
email: str = Field(..., description="유저 이메일")

# [내부용] DB 조회 및 서버 내부 인증용 (UserData 상속 + 암호화된 비밀번호)
class UserDataPASS(UserData):
hashed_password: str
"""
[내부용] DB 조회 및 서버 내부 인증용 (UserData 상속 + 암호화된 비밀번호)
"""
hashed_password: str = Field(..., description="bcrypt로 해싱된 비밀번호 (서버 내부 인증용, 외부 노출 금지)")

# [요청용] 로그인 API (POST /auth/login) 수신 JSON 데이터 검증
class LoginRequest(BaseModel):
email: EmailStr
password: str = Field(min_length=8, max_length=30)
"""
[요청용] 로그인 API (POST /auth/login) 수신 JSON 데이터 검증
"""
email: EmailStr = Field(..., description="로그인 이메일")
password: str = Field(min_length=8, max_length=30, description="비밀번호 (8자 이상 30자 이하)")

# [요청용] 회원가입 API (POST /auth/register) 수신 JSON 데이터 검증
class RegisterRequest(LoginRequest):
name: str = Field(min_length=2, max_length=100)
"""
[요청용] 회원가입 API (POST /auth/register) 수신 JSON 데이터 검증
"""
name: str = Field(min_length=2, max_length=100, description="유저 이름 (2자 이상 100자 이하)")
69 changes: 52 additions & 17 deletions App/schemas/image_schema.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,60 @@
from pydantic import BaseModel
from datetime import datetime
from pydantic import BaseModel, Field

class BaseMetadata(BaseModel):
image_id: int
image_loc: str
label: str
version_type: str
model_type: str
domain_type: str
created_at: datetime
"""
[공통 메타데이터] 이미지 분석 결과의 기본 식별 정보

- routes: image (히스토리 조회)
- services: image_svc.get_image_result, get_user_histories, get_user_history
"""
image_id: int = Field(..., description="이미지 분석 레코드 고유 ID (image_result.id)")
image_loc: str = Field(..., description="서버 내 저장된 이미지 파일 경로 (DB 저장 형식, 예: /static/uploads/user@a.com/img_1700000000.png)")
label: str = Field(..., description="딥페이크 판정 결과 라벨 (FAKE / REAL / UNKNOWN)")
version_type: str = Field(..., description="사용된 모델 버전 (v1 / v2)")
model_type: str = Field(..., description="모델 속도/정확도 모드 (fast / pro)")
domain_type: str = Field(..., description="얼굴 도메인 타입 (서양인 / 동양인)")
created_at: datetime = Field(..., description="분석 요청 생성 시각 (UTC)")

class InferenceResult(BaseModel):
score : float
face_conf : float
face_ratio : float
face_brightness : float
result_msg : str
"""
[추론 상세 결과] 딥페이크 분석 수치 결과

- 상속 베이스 클래스 (직접 응답 X)
- 상속처: UserHistory_indi, ImageData_indi
- 사용처: image (GET /image/history/{image_id}), inference (GET /inference/image/{image_id})
- services: image_svc.get_user_history, image_svc.get_image_result
"""
score: float = Field(..., description="딥페이크 확률 점수 (0.0~1.0, 0.5 이상이면 FAKE 판정). 분석 실패 시 -1.0")
face_conf: float = Field(..., description="얼굴 탐지 신뢰도 (0.0~1.0). 분석 실패 시 -1.0")
face_ratio: float = Field(..., description="이미지 내 얼굴이 차지하는 면적 비율 (0.0~1.0). 분석 실패 시 -1.0")
face_brightness: float = Field(..., description="얼굴 영역 평균 밝기 값. 분석 실패 시 -1.0")
result_msg: str = Field(..., description="분석 결과에 대한 상세 메시지 (성공/경고/실패 사유)")

class UserHistory(BaseMetadata):
user_id: int
"""
[히스토리 목록] 회원 전체 이미지 분석 이력

- routes: image (GET /image/history)
- services: image_svc.get_user_histories
"""
user_id: int = Field(..., description="분석을 요청한 유저 ID (user.id FK)")

class UserHistory_indi(UserHistory, InferenceResult):
class UserHistory_indi(UserHistory, InferenceResult):
"""
[히스토리 상세] 회원 개별 이미지 분석 상세 결과

- routes: image (GET /image/history/{image_id}, DELETE /image/history/{image_id} - 내부 조회)
- services: image_svc.get_user_history
"""
status: str

class ImageData_indi(BaseMetadata, InferenceResult):
user_id : int | None
status : str
"""
[추론 결과 조회] 분석 진행 상태 + 최종 결과 (회원/비회원 공통)

- routes: inference (GET /inference/image/{image_id})
- services: image_svc.get_image_result
"""
user_id: int | None = Field(None, description="유저 ID. 비회원 분석 요청의 경우 None")
status: str = Field(..., description="분석 진행 상태 (PENDING / SUCCESS / WARNING / FAILED)", examples=["SUCCESS"])
95 changes: 57 additions & 38 deletions App/schemas/video_schema.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,69 @@
from pydantic import BaseModel
from datetime import datetime
from pydantic import BaseModel, Field

# [히스토리 목록] GET /video/history
# 사용자 전체 비디오 히스토리 조회
class VideoData(BaseModel):
id: int
user_id : int | None
video_loc : str
status : str
label : str
version_type : str
model_type : str
domain_type : str
created_at : datetime
"""
[히스토리 목록] 사용자 전체 비디오 히스토리 조회

- routes: video (GET /video/history)
- services: video_svc.get_user_histories
"""
id: int = Field(..., description="비디오 분석 레코드 고유 ID (video_result.id)")
user_id: int | None = Field(None, description="분석 요청 유저 ID. 비회원의 경우 None")
video_loc: str = Field(..., description="서버 내 저장된 비디오 파일 경로 (예: /static/uploads/user@a.com/vid_1700000000.mp4)")
status: str = Field(..., description="분석 진행 상태 (PENDING / SUCCESS / WARNING / FAILED)")
label: str = Field(..., description="딥페이크 판정 결과 라벨 (FAKE / REAL / UNKNOWN)")
version_type: str = Field(..., description="사용된 모델 버전 (v1 / v2)")
model_type: str = Field(..., description="모델 속도/정확도 모드 (fast / pro)")
domain_type: str = Field(..., description="얼굴 도메인 타입 (서양인 / 동양인)")
created_at: datetime = Field(..., description="분석 요청 생성 시각 (UTC)")

# [히스토리 상세 / 추론 결과] GET /video/history/{video_id}, GET /inference/video/{video_id}
# 개별 비디오 상세 조회 + 추론 결과값 포함
class VideoDetailData(VideoData):
"""
[히스토리 상세 / 추론 결과] 개별 비디오 상세 + 추론 수치 결과

score : float
face_conf : float
face_ratio : float
face_brightness : float
result_msg : str
- routes: video (GET /video/history/{video_id}), inference (GET /inference/video/{video_id})
- services: video_svc.get_user_history, video_svc.get_video_result
"""
score: float = Field(..., description="비디오 전체 평균 딥페이크 확률 (0.0~1.0). 실패 시 -1.0")
face_conf: float = Field(..., description="평균 얼굴 탐지 신뢰도. 실패 시 -1.0")
face_ratio: float = Field(..., description="평균 얼굴 면적 비율. 실패 시 -1.0")
face_brightness: float = Field(..., description="평균 얼굴 영역 밝기. 실패 시 -1.0")
result_msg: str = Field(..., description="분석 결과 상세 메시지")

# [프레임별 추론 결과] GET /inference/video/{video_id}/detail 응답 내부
# video_frame_result 테이블 row 단위 매핑
class VideoFrameData(BaseModel):
frame_index: int
frame_time: float
score: float
face_conf: float
face_ratio: float
face_brightness: float
"""
[프레임별 추론 결과] 비디오 프레임 단위 분석 결과

# [비디오 메타 정보] GET /inference/video/{video_id}/detail 응답 내부
# video_meta_result 테이블 row 단위 매핑
- routes: inference (GET /inference/video/{video_id}/detail 응답 내부)
- services: video_svc.get_video_frame_result, save_video_frame_result
"""
frame_index: int = Field(..., description="비디오 내 프레임 인덱스 (0부터 시작)")
frame_time: float = Field(..., description="해당 프레임의 영상 내 재생 시점 (초 단위)")
score: float = Field(..., description="해당 프레임의 딥페이크 확률 점수 (0.0~1.0)")
face_conf: float = Field(..., description="해당 프레임 얼굴 탐지 신뢰도")
face_ratio: float = Field(..., description="해당 프레임 얼굴 면적 비율")
face_brightness: float = Field(..., description="해당 프레임 얼굴 영역 밝기")

class VideoMetaData(BaseModel):
fps: float
total_frames: int # 전체 프레임 수
num_sampled: int # 샘플링 대상 프레임 수
num_extracted: int # 실제 추출된 프레임 수
num_detected: int # 얼굴 탐지 성공 프레임 수
"""
[비디오 메타 정보] 비디오 전체 프레임 처리 통계

- routes: inference (GET /inference/video/{video_id}/detail 응답 내부)
- services: video_svc.get_video_meta_result, save_video_meta_result
"""
fps: float = Field(..., description="비디오의 초당 프레임 수 (Frames Per Second)")
total_frames: int = Field(..., description="비디오 전체 프레임 수")
num_sampled: int = Field(..., description="추론을 위해 샘플링한 프레임 수")
num_extracted: int = Field(..., description="실제로 추출에 성공한 프레임 수")
num_detected: int = Field(..., description="얼굴 탐지에 성공한 프레임 수 (score 산출 성공)")

# [상세 분석 최종 응답] GET /inference/video/{video_id}/{detail}
# 로그인 유저 전용 (get_session_user_prt)
class VideoDetailResponse(BaseModel):
meta: VideoMetaData
frames: list[VideoFrameData]
"""
[상세 분석 최종 응답] 비디오 상세 분석 화면용 통합 응답

사용처:
- routes: inference (GET /inference/video/{video_id}/detail) - 로그인 유저 전용
"""
meta: VideoMetaData = Field(..., description="비디오 메타 정보 (FPS, 프레임 수 등)")
frames: list[VideoFrameData] = Field(..., description="프레임별 상세 분석 결과 리스트 (frame_index 오름차순)")
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading