Spaces:
Running
Running
File size: 5,049 Bytes
74cf6bd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
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)}"
)
|