from typing import Any from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app import crud, schemas from app.api import deps router = APIRouter() @router.get("/", response_model=list[schemas.MangaWithRelations]) def read_manga( db: Session = Depends(deps.get_db), skip: int = 0, limit: int = 100, title: str | None = None, author_id: int | None = None, publisher_id: int | None = None, genre_id: int | None = None, in_stock: bool | None = None, ) -> Any: """ Retrieve manga. - **title**: Optional filter by title (partial match) - **author_id**: Optional filter by author ID - **publisher_id**: Optional filter by publisher ID - **genre_id**: Optional filter by genre ID - **in_stock**: Optional filter by stock availability """ if any([title, author_id, publisher_id, genre_id, in_stock is not None]): # Search with filters manga = crud.manga.search( db, title=title, author_id=author_id, publisher_id=publisher_id, genre_id=genre_id, in_stock=in_stock, skip=skip, limit=limit, ) else: # Get all manga manga = crud.manga.get_multi(db, skip=skip, limit=limit) return manga @router.post("/", response_model=schemas.MangaWithRelations) def create_manga( *, db: Session = Depends(deps.get_db), manga_in: schemas.MangaCreate, ) -> Any: """ Create new manga. """ # Check if ISBN exists and is not empty if manga_in.isbn: manga = crud.manga.get_by_isbn(db, isbn=manga_in.isbn) if manga: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="A manga with this ISBN already exists.", ) # Validate author_id if provided if manga_in.author_id: author = crud.author.get(db, id=manga_in.author_id) if not author: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Author with ID {manga_in.author_id} not found.", ) # Validate publisher_id if provided if manga_in.publisher_id: publisher = crud.publisher.get(db, id=manga_in.publisher_id) if not publisher: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Publisher with ID {manga_in.publisher_id} not found.", ) # Validate genre_ids if provided if manga_in.genre_ids: for genre_id in manga_in.genre_ids: genre = crud.genre.get(db, id=genre_id) if not genre: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Genre with ID {genre_id} not found.", ) manga = crud.manga.create(db, obj_in=manga_in) return manga @router.get("/{manga_id}", response_model=schemas.MangaWithRelations) def read_manga_by_id( *, db: Session = Depends(deps.get_db), manga_id: int, ) -> Any: """ Get manga by ID. """ manga = crud.manga.get(db, id=manga_id) if not manga: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Manga not found", ) return manga @router.put("/{manga_id}", response_model=schemas.MangaWithRelations) def update_manga( *, db: Session = Depends(deps.get_db), manga_id: int, manga_in: schemas.MangaUpdate, ) -> Any: """ Update a manga. """ manga = crud.manga.get(db, id=manga_id) if not manga: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Manga not found", ) # Check if ISBN is being updated and already exists if manga_in.isbn and manga_in.isbn != manga.isbn: existing_manga = crud.manga.get_by_isbn(db, isbn=manga_in.isbn) if existing_manga: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="A manga with this ISBN already exists.", ) # Validate author_id if provided if manga_in.author_id: author = crud.author.get(db, id=manga_in.author_id) if not author: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Author with ID {manga_in.author_id} not found.", ) # Validate publisher_id if provided if manga_in.publisher_id: publisher = crud.publisher.get(db, id=manga_in.publisher_id) if not publisher: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Publisher with ID {manga_in.publisher_id} not found.", ) # Validate genre_ids if provided if manga_in.genre_ids: for genre_id in manga_in.genre_ids: genre = crud.genre.get(db, id=genre_id) if not genre: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Genre with ID {genre_id} not found.", ) manga = crud.manga.update(db, db_obj=manga, obj_in=manga_in) return manga @router.delete("/{manga_id}", response_model=schemas.Manga) def delete_manga( *, db: Session = Depends(deps.get_db), manga_id: int, ) -> Any: """ Delete a manga. """ manga = crud.manga.get(db, id=manga_id) if not manga: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Manga not found", ) manga = crud.manga.remove(db, id=manga_id) return manga