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