lukawskikacper's picture
Vibe coded implementation (with some manual fixes)
74cf6bd
from fastapi import APIRouter, HTTPException, Query
from typing import List, Optional
from app.models.video import Video, SearchResult, VideoSegment
from app.services.video_service import (
process_video,
search_video_segments,
get_all_segments,
get_processed_videos,
get_video_by_id,
)
from pydantic import BaseModel
router = APIRouter()
class VideoRequest(BaseModel):
url: str
class VideoResponse(BaseModel):
"""Response model for video processing with additional status information."""
video: Video
newly_processed: bool = False
@router.post("/process", response_model=VideoResponse)
async def process_video_endpoint(video_request: VideoRequest) -> VideoResponse:
"""Process a YouTube video to extract and store transcript segments.
If the video has already been processed, returns the existing data without reprocessing."""
try:
import logging
# Get the video ID first
from app.services.video_service import extract_video_id, get_video_by_id
video_id = extract_video_id(video_request.url)
# Check if already processed
existing_video = get_video_by_id(video_id)
already_processed = existing_video is not None and existing_video.processed
if already_processed:
logging.info(f"Video {video_id} already processed, returning existing data")
return VideoResponse(video=existing_video, newly_processed=False)
# Process the video if needed
result = process_video(video_request.url)
return VideoResponse(video=result, newly_processed=True)
except Exception as e:
import logging
import traceback
logging.error(f"Error processing video URL {video_request.url}: {str(e)}")
logging.error(traceback.format_exc())
raise HTTPException(status_code=500, detail=str(e))
@router.get("/search")
async def search_video_endpoint(
query: str = Query(..., description="Search query for video content"),
video_id: Optional[str] = Query(
None, description="Optional YouTube video ID to limit search"
),
limit: int = Query(5, description="Maximum number of results to return"),
) -> List[SearchResult]:
"""Search for video segments based on the provided query."""
import logging
# Check for invalid video_id
if video_id and (video_id.lower() == "undefined" or video_id.lower() == "null"):
logging.warning(f"Invalid video_id in search request: '{video_id}'")
video_id = None # Clear invalid video_id to perform a global search instead
try:
results = search_video_segments(query, video_id, limit)
return results
except Exception as e:
logging.error(
f"Error searching for query '{query}' with video_id '{video_id}': {str(e)}"
)
raise HTTPException(status_code=500, detail=str(e))
@router.get("/segments/{video_id}")
async def get_segments_endpoint(video_id: str) -> List[VideoSegment]:
"""Get all segments for a specific video, ordered by start time."""
import logging
# Check for invalid video ID
if not video_id or video_id.lower() == "undefined" or video_id.lower() == "null":
logging.warning(f"Invalid video ID requested: '{video_id}'")
return [] # Return empty list for invalid IDs to avoid frontend errors
try:
segments = get_all_segments(video_id)
if not segments:
# Return an empty list instead of 404 to allow frontend to handle gracefully
return []
return segments
except Exception as e:
# Log the exception for debugging
logging.error(f"Error getting segments for video {video_id}: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Could not retrieve video segments: {str(e)}"
)
@router.get("/recent")
async def get_recent_videos_endpoint(
limit: int = Query(10, description="Maximum number of videos to return"),
) -> List[Video]:
"""Get recently processed videos ordered by creation time."""
try:
videos = get_processed_videos(limit=limit)
return videos
except Exception as e:
# Log the exception for debugging
import logging
logging.error(f"Error getting recent videos: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Could not retrieve recent videos: {str(e)}"
)
@router.get("/info/{video_id}")
async def get_video_info_endpoint(video_id: str) -> Video:
"""Get metadata for a specific video."""
try:
video = get_video_by_id(video_id)
if not video:
# Return a basic video object if not found in database
return Video(video_id=video_id, title=f"Video {video_id}")
return video
except Exception as e:
import logging
logging.error(f"Error getting video info for {video_id}: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Could not retrieve video info: {str(e)}"
)