mirror of
https://github.com/wowlikon/LiB.git
synced 2026-03-21 15:43:38 +00:00
Исправление документации swagger и ошибок обновления данных
This commit is contained in:
@@ -45,6 +45,7 @@ coverage.xml
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
.ruff_cache/
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
@@ -25,7 +25,7 @@ class AuthorCreate(AuthorBase):
|
||||
class AuthorUpdate(SQLModel):
|
||||
"""Модель автора для обновления"""
|
||||
|
||||
name: str | None = Field(None, description="Псевдоним")
|
||||
name: str | None = Field(None, description="Псевдоним", schema_extra={"examples": [None]})
|
||||
|
||||
|
||||
class AuthorRead(AuthorBase):
|
||||
|
||||
@@ -35,10 +35,10 @@ class BookCreate(BookBase):
|
||||
class BookUpdate(SQLModel):
|
||||
"""Модель книги для обновления"""
|
||||
|
||||
title: str | None = Field(None, description="Название")
|
||||
description: str | None = Field(None, description="Описание")
|
||||
page_count: int | None = Field(None, description="Количество страниц")
|
||||
status: BookStatus | None = Field(None, description="Статус")
|
||||
title: str | None = Field(None, description="Название", schema_extra={"examples": [None]})
|
||||
description: str | None = Field(None, description="Описание", schema_extra={"examples": [None]})
|
||||
page_count: int | None = Field(None, description="Количество страниц", schema_extra={"examples": [None]})
|
||||
status: BookStatus | None = Field(None, description="Статус", schema_extra={"examples": [None]})
|
||||
|
||||
|
||||
class BookRead(BookBase):
|
||||
|
||||
@@ -25,7 +25,7 @@ class GenreCreate(GenreBase):
|
||||
class GenreUpdate(SQLModel):
|
||||
"""Модель жанра для обновления"""
|
||||
|
||||
name: str | None = Field(None, description="Название")
|
||||
name: str | None = Field(None, description="Название", schema_extra={"examples": [None]})
|
||||
|
||||
|
||||
class GenreRead(GenreBase):
|
||||
|
||||
@@ -104,7 +104,7 @@ class UserUpdateByAdmin(UserUpdate):
|
||||
"""Обновление пользователя администратором"""
|
||||
|
||||
is_active: bool = Field(True, description="Не является ли заблокированным")
|
||||
roles: list[str] | None = Field(None, description="Роли")
|
||||
roles: list[str] | None = Field(None, description="Роли", schema_extra={"examples": [None]})
|
||||
|
||||
|
||||
class LoginResponse(SQLModel):
|
||||
|
||||
@@ -71,9 +71,9 @@ class UserRead(UserBase):
|
||||
class UserUpdate(SQLModel):
|
||||
"""Модель пользователя для обновления"""
|
||||
|
||||
email: EmailStr | None = Field(None, description="Email")
|
||||
full_name: str | None = Field(None, description="Полное имя")
|
||||
password: str | None = Field(None, description="Пароль")
|
||||
email: EmailStr | None = Field(None, description="Email", schema_extra={"examples": [None]})
|
||||
full_name: str | None = Field(None, description="Полное имя", schema_extra={"examples": [None]})
|
||||
password: str | None = Field(None, description="Пароль", schema_extra={"examples": [None]})
|
||||
|
||||
|
||||
class UserList(SQLModel):
|
||||
|
||||
@@ -105,6 +105,8 @@ def update_author(
|
||||
|
||||
update_data = author.model_dump(exclude_unset=True)
|
||||
for field, value in update_data.items():
|
||||
if value is None:
|
||||
continue
|
||||
setattr(db_author, field, value)
|
||||
|
||||
session.commit()
|
||||
|
||||
@@ -62,7 +62,12 @@ from sqlalchemy import select, func, distinct, case, exists
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
|
||||
@router.get("/filter", response_model=BookFilteredList)
|
||||
@router.get(
|
||||
"/filter",
|
||||
response_model=BookFilteredList,
|
||||
summary="Поиск по книгам",
|
||||
description="Фильтрует и ищет книги",
|
||||
)
|
||||
def filter_books(
|
||||
current_user: OptionalAuth,
|
||||
session: Session = Depends(get_session),
|
||||
@@ -74,6 +79,7 @@ def filter_books(
|
||||
page: int = Query(1, gt=0),
|
||||
size: int = Query(20, gt=0, le=100),
|
||||
):
|
||||
"""Выполняет поиск книги в системе"""
|
||||
statement = select(Book).options(
|
||||
selectinload(Book.authors), selectinload(Book.genres), defer(Book.embedding) # ty: ignore
|
||||
)
|
||||
@@ -315,13 +321,18 @@ def delete_book(
|
||||
session.commit()
|
||||
return book_read
|
||||
|
||||
@router.post("/{book_id}/preview")
|
||||
@router.post(
|
||||
"/{book_id}/preview",
|
||||
summary="Утановить обложку книги",
|
||||
description="Меняет обложку книги в системе",
|
||||
)
|
||||
async def upload_book_preview(
|
||||
current_user: RequireStaff,
|
||||
file: UploadFile = File(...),
|
||||
book_id: int = Path(..., gt=0),
|
||||
session: Session = Depends(get_session)
|
||||
):
|
||||
"""Загружает обложку книги в систему"""
|
||||
if not (file.content_type or "").startswith("image/"):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,
|
||||
@@ -369,12 +380,17 @@ async def upload_book_preview(
|
||||
}
|
||||
|
||||
|
||||
@router.delete("/{book_id}/preview")
|
||||
@router.delete(
|
||||
"/{book_id}/preview",
|
||||
summary="Удалить обложку книги",
|
||||
description="Удаляет обложку книги в системе",
|
||||
)
|
||||
async def remove_book_preview(
|
||||
current_user: RequireStaff,
|
||||
book_id: int = Path(..., gt=0),
|
||||
session: Session = Depends(get_session)
|
||||
):
|
||||
"""Убирает обложку книги в системе"""
|
||||
book = session.get(Book, book_id)
|
||||
if not book:
|
||||
raise HTTPException(status.HTTP_404_NOT_FOUND, "Book not found")
|
||||
|
||||
@@ -104,6 +104,8 @@ def update_genre(
|
||||
|
||||
update_data = genre.model_dump(exclude_unset=True)
|
||||
for field, value in update_data.items():
|
||||
if value is None:
|
||||
continue
|
||||
setattr(db_genre, field, value)
|
||||
|
||||
session.commit()
|
||||
|
||||
+4
-2
@@ -1,7 +1,9 @@
|
||||
[project]
|
||||
name = "LiB"
|
||||
version = "0.9.0"
|
||||
description = "Это простое API для управления авторами, книгами и их жанрами."
|
||||
version = "0.9.1"
|
||||
description = """REST API библиотечной системы. Позволяет вести каталог книг с авторами и жанрами, отслеживать выдачи и возвраты книг читателями.
|
||||
С ролевой моделью: читатель, библиотекарь, администратор. Для авторизованных пользователей доступен векторный поиск книг по названию и описанию.
|
||||
Для безопасности используется шифрование, CAPTCH, 2FA и одноразовые коды коды восстановления пароля."""
|
||||
authors = [{ name = "wowlikon" }]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
Reference in New Issue
Block a user