Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions app/api/decks.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import typing

import litestar
from advanced_alchemy.exceptions import NotFoundError
from litestar import status_codes
from litestar.exceptions import HTTPException
from litestar.params import FromPath # noqa: TC002
from litestar.plugins.pydantic import PydanticDTO

Expand All @@ -20,9 +17,6 @@ async def list_decks(decks_repository: DecksRepository) -> schemas.Decks:
@litestar.get("/decks/{deck_id:int}/")
async def get_deck(deck_id: FromPath[int], decks_repository: DecksRepository) -> schemas.Deck:
instance = await decks_repository.fetch_with_cards(deck_id)
if not instance:
raise HTTPException(status_code=status_codes.HTTP_404_NOT_FOUND, detail="Deck is not found")

return schemas.Deck.model_validate(instance)


Expand All @@ -32,10 +26,7 @@ async def update_deck(
data: schemas.DeckCreate,
decks_repository: DecksRepository,
) -> schemas.Deck:
try:
instance = await decks_repository.update(data=data.model_dump(), item_id=deck_id)
except NotFoundError:
raise HTTPException(status_code=status_codes.HTTP_404_NOT_FOUND, detail="Deck is not found") from None
instance = await decks_repository.update(data=data.model_dump(), item_id=deck_id)
return schemas.Deck.model_validate(instance)


Expand All @@ -53,9 +44,7 @@ async def list_cards(deck_id: FromPath[int], cards_repository: CardsRepository)

@litestar.get("/cards/{card_id:int}/", return_dto=PydanticDTO[schemas.Card])
async def get_card(card_id: FromPath[int], cards_repository: CardsRepository) -> schemas.Card:
instance = await cards_repository.get_one_or_none(models.Card.id == card_id)
if not instance:
raise HTTPException(status_code=status_codes.HTTP_404_NOT_FOUND, detail="Card is not found")
instance = await cards_repository.get_one(models.Card.id == card_id)
return schemas.Card.model_validate(instance)


Expand Down
3 changes: 2 additions & 1 deletion app/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import modern_di
import modern_di_litestar
from advanced_alchemy.exceptions import DuplicateKeyError
from advanced_alchemy.exceptions import DuplicateKeyError, NotFoundError
from lite_bootstrap import LitestarBootstrapper
from litestar.config.app import AppConfig
from opentelemetry.instrumentation.asyncpg import AsyncPGInstrumentor
Expand All @@ -25,6 +25,7 @@ def build_app() -> litestar.Litestar:
application_config=AppConfig(
exception_handlers={ # ty: ignore[invalid-argument-type]
DuplicateKeyError: exceptions.duplicate_key_error_handler,
NotFoundError: exceptions.not_found_error_handler,
},
route_handlers=[ROUTER],
plugins=[modern_di_litestar.ModernDIPlugin(di_container)],
Expand Down
10 changes: 9 additions & 1 deletion app/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


if typing.TYPE_CHECKING:
from advanced_alchemy.exceptions import DuplicateKeyError
from advanced_alchemy.exceptions import DuplicateKeyError, NotFoundError


def duplicate_key_error_handler(_: object, exc: DuplicateKeyError) -> litestar.Response[dict[str, typing.Any]]:
Expand All @@ -14,3 +14,11 @@ def duplicate_key_error_handler(_: object, exc: DuplicateKeyError) -> litestar.R
content={"detail": exc.detail},
status_code=status_codes.HTTP_400_BAD_REQUEST,
)


def not_found_error_handler(_: object, __: NotFoundError) -> litestar.Response[dict[str, typing.Any]]:
return litestar.Response(
media_type=litestar.MediaType.JSON,
content={"detail": "Not found"},
status_code=status_codes.HTTP_404_NOT_FOUND,
)
4 changes: 2 additions & 2 deletions app/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class BaseRepository(SQLAlchemyAsyncRepository[models.Deck]):

repository_type = BaseRepository

async def fetch_with_cards(self, deck_id: int) -> models.Deck | None:
return await self.get_one_or_none(
async def fetch_with_cards(self, deck_id: int) -> models.Deck:
return await self.get_one(
models.Deck.id == deck_id,
load=[orm.selectinload(models.Deck.cards)],
)
Expand Down