from typing import Any, Optional from fastapi import APIRouter, Depends, HTTPException, Query, Path from sqlalchemy.orm import Session from app.api import crud from app.api.schemas.genre import ( Genre, GenreCreate, GenreUpdate, GenreDetails, GenreList ) from app.db.session import get_db router = APIRouter(prefix="/genres") @router.get("", response_model=GenreList) def read_genres( db: Session = Depends(get_db), skip: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=100), name: Optional[str] = None, movie_id: Optional[int] = None, ) -> Any: """ Retrieve all genres with optional filtering. """ # Build filter dict from query parameters filters = {} if name: filters["name"] = name if movie_id: filters["movie_id"] = movie_id genres, total = crud.genre.get_multi(db, skip=skip, limit=limit, filters=filters) return {"data": genres, "total": total} @router.post("", response_model=Genre, status_code=201) def create_genre( *, db: Session = Depends(get_db), genre_in: GenreCreate, ) -> Any: """ Create a new genre. """ # Check if a genre with this name already exists existing_genre = crud.genre.get_by_name(db, name=genre_in.name) if existing_genre: raise HTTPException( status_code=400, detail=f"Genre with name {genre_in.name} already exists" ) genre = crud.genre.create(db, genre_in=genre_in) return genre @router.get("/{genre_id}", response_model=GenreDetails) def read_genre( *, db: Session = Depends(get_db), genre_id: int = Path(..., ge=1), ) -> Any: """ Get a specific genre by ID. """ genre = crud.genre.get(db, genre_id=genre_id) if not genre: raise HTTPException(status_code=404, detail="Genre not found") return genre @router.put("/{genre_id}", response_model=Genre) def update_genre( *, db: Session = Depends(get_db), genre_id: int = Path(..., ge=1), genre_in: GenreUpdate, ) -> Any: """ Update a genre. """ genre = crud.genre.get(db, genre_id=genre_id) if not genre: raise HTTPException(status_code=404, detail="Genre not found") # Check if another genre with the new name already exists if genre_in.name and genre_in.name != genre.name: existing_genre = crud.genre.get_by_name(db, name=genre_in.name) if existing_genre: raise HTTPException( status_code=400, detail=f"Genre with name {genre_in.name} already exists" ) genre = crud.genre.update(db, db_genre=genre, genre_in=genre_in) return genre @router.delete("/{genre_id}", status_code=204, response_model=None) def delete_genre( *, db: Session = Depends(get_db), genre_id: int = Path(..., ge=1), ) -> Any: """ Delete a genre. """ success = crud.genre.delete(db, genre_id=genre_id) if not success: raise HTTPException(status_code=404, detail="Genre not found") return None