from typing import Any, List, Optional from fastapi import APIRouter, Depends, HTTPException, Query, Path from sqlalchemy.orm import Session from app.api import crud from app.api.schemas.movie import ( Movie, MovieCreate, MovieUpdate, MovieDetails, MovieList ) from app.db.session import get_db router = APIRouter(prefix="/movies") @router.get("", response_model=MovieList) def read_movies( db: Session = Depends(get_db), skip: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=100), title: Optional[str] = None, director_id: Optional[int] = None, genre_id: Optional[int] = None, actor_id: Optional[int] = None, min_rating: Optional[float] = Query(None, ge=0, le=10), year: Optional[int] = None, ) -> Any: """ Retrieve all movies with optional filtering. """ # Build filter dict from query parameters filters = {} if title: filters["title"] = title if director_id: filters["director_id"] = director_id if genre_id: filters["genre_id"] = genre_id if actor_id: filters["actor_id"] = actor_id if min_rating is not None: filters["min_rating"] = min_rating if year: filters["year"] = year movies, total = crud.movie.get_multi(db, skip=skip, limit=limit, filters=filters) return {"data": movies, "total": total} @router.post("", response_model=Movie, status_code=201) def create_movie( *, db: Session = Depends(get_db), movie_in: MovieCreate, ) -> Any: """ Create a new movie. """ movie = crud.movie.create(db, movie_in=movie_in) return movie @router.get("/{movie_id}", response_model=MovieDetails) def read_movie( *, db: Session = Depends(get_db), movie_id: int = Path(..., ge=1), ) -> Any: """ Get a specific movie by ID. """ movie = crud.movie.get(db, movie_id=movie_id) if not movie: raise HTTPException(status_code=404, detail="Movie not found") return movie @router.put("/{movie_id}", response_model=Movie) def update_movie( *, db: Session = Depends(get_db), movie_id: int = Path(..., ge=1), movie_in: MovieUpdate, ) -> Any: """ Update a movie. """ movie = crud.movie.get(db, movie_id=movie_id) if not movie: raise HTTPException(status_code=404, detail="Movie not found") movie = crud.movie.update(db, db_movie=movie, movie_in=movie_in) return movie @router.delete("/{movie_id}", status_code=204, response_model=None) def delete_movie( *, db: Session = Depends(get_db), movie_id: int = Path(..., ge=1), ) -> Any: """ Delete a movie. """ success = crud.movie.delete(db, movie_id=movie_id) if not success: raise HTTPException(status_code=404, detail="Movie not found") return None @router.get("/search/{query}", response_model=List[Movie]) def search_movies( *, db: Session = Depends(get_db), query: str = Path(..., min_length=2), limit: int = Query(10, ge=1, le=100), ) -> Any: """ Search for movies by title or overview. """ movies = crud.movie.search(db, query=query, limit=limit) return movies