Форматирование кода, добавление лого, исправление тестов, улучшение эндпоинтов и документации

This commit is contained in:
2025-11-30 20:03:39 +03:00
parent a3ccd8a466
commit 99de648fa9
38 changed files with 1261 additions and 308 deletions

View File

@@ -1,17 +1,27 @@
from fastapi import APIRouter, Depends, HTTPException
from fastapi import APIRouter, Path, Depends, HTTPException
from sqlmodel import Session, select
from library_service.settings import get_session
from library_service.models.db import Genre, GenreBookLink, Book, GenreWithBooks
from library_service.models.dto import (
GenreCreate, GenreUpdate, GenreRead,
GenreList, BookRead
GenreCreate,
GenreUpdate,
GenreRead,
GenreList,
BookRead,
)
router = APIRouter(prefix="/genres", tags=["genres"])
# Create a genre
@router.post("/", response_model=GenreRead)
@router.post(
"/",
response_model=GenreRead,
summary="Создать жанр",
description="Добавляет жанр книг в систему",
)
def create_genre(genre: GenreCreate, session: Session = Depends(get_session)):
db_genre = Genre(**genre.model_dump())
session.add(db_genre)
@@ -19,41 +29,59 @@ def create_genre(genre: GenreCreate, session: Session = Depends(get_session)):
session.refresh(db_genre)
return GenreRead(**db_genre.model_dump())
# Read genres
@router.get("/", response_model=GenreList)
@router.get(
"/",
response_model=GenreList,
summary="Получить список жанров",
description="Возвращает список всех жанров в системе",
)
def read_genres(session: Session = Depends(get_session)):
genres = session.exec(select(Genre)).all()
return GenreList(
genres=[GenreRead(**genre.model_dump()) for genre in genres],
total=len(genres)
genres=[GenreRead(**genre.model_dump()) for genre in genres], total=len(genres)
)
# Read a genre with their books
@router.get("/{genre_id}", response_model=GenreWithBooks)
def get_genre(genre_id: int, session: Session = Depends(get_session)):
@router.get(
"/{genre_id}",
response_model=GenreWithBooks,
summary="Получить информацию о жанре",
description="Возвращает информацию о жанре и книгах с ним",
)
def get_genre(
genre_id: int = Path(..., description="ID жанра (целое число, > 0)", gt=0),
session: Session = Depends(get_session),
):
genre = session.get(Genre, genre_id)
if not genre:
raise HTTPException(status_code=404, detail="Genre not found")
books = session.exec(
select(Book)
.join(GenreBookLink)
.where(GenreBookLink.genre_id == genre_id)
select(Book).join(GenreBookLink).where(GenreBookLink.genre_id == genre_id)
).all()
book_reads = [BookRead(**book.model_dump()) for book in books]
genre_data = genre.model_dump()
genre_data['books'] = book_reads
genre_data["books"] = book_reads
return GenreWithBooks(**genre_data)
# Update a genre
@router.put("/{genre_id}", response_model=GenreRead)
@router.put(
"/{genre_id}",
response_model=GenreRead,
summary="Обновляет информацию о жанре",
description="Обновляет информацию о жанре в системе",
)
def update_genre(
genre_id: int,
genre: GenreUpdate,
session: Session = Depends(get_session)
genre_id: int = Path(..., description="ID жанра (целое число, > 0)", gt=0),
session: Session = Depends(get_session),
):
db_genre = session.get(Genre, genre_id)
if not db_genre:
@@ -67,9 +95,18 @@ def update_genre(
session.refresh(db_genre)
return GenreRead(**db_genre.model_dump())
# Delete a genre
@router.delete("/{genre_id}", response_model=GenreRead)
def delete_genre(genre_id: int, session: Session = Depends(get_session)):
@router.delete(
"/{genre_id}",
response_model=GenreRead,
summary="Удалить жанр",
description="Удаляет автора из системы",
)
def delete_genre(
genre_id: int = Path(..., description="ID жанра (целое число, > 0)", gt=0),
session: Session = Depends(get_session),
):
genre = session.get(Genre, genre_id)
if not genre:
raise HTTPException(status_code=404, detail="Genre not found")