secretsanta/apps/http/litestar/app.py
2023-12-09 11:29:28 +01:00

73 lines
2 KiB
Python

from dataclasses import asdict, dataclass
from typing import Annotated, Literal
from litestar import Controller, Litestar, MediaType, Response, get, put
from litestar.params import Parameter
from pydantic import UUID4
from secretsanta.domain import Group
from secretsanta.repo import S3Repo
from secretsanta.service import (
CreateGroupService,
GetGroupParticipantsService,
GetPairService,
)
from secretsanta.settings import get_config
@dataclass
class CreateGroup:
participants: list[str]
@dataclass
class PairResponse:
pair: str
class GroupController(Controller):
path = "api/v1/groups"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.repo = S3Repo()
self.get_participants_service = GetGroupParticipantsService(self.repo)
self.create_group_service = CreateGroupService(self.repo)
self.get_pair_service = GetPairService(self.repo)
@get("/{group_uuid:uuid}")
async def get_participants(self, group_uuid: UUID4) -> list[str]:
return await self.get_participants_service.run(group_uuid)
@put("/{group_uuid:uuid}")
async def create_group(
self,
group_uuid: UUID4,
data: CreateGroup,
) -> list[str]:
return await self.create_group_service.run(
Group(uuid=group_uuid, **asdict(data)),
)
@get("/{group_uuid:uuid}/pair/{participant_name:str}")
async def get_pair(
self,
group_uuid: UUID4,
participant_name: str,
response_type: Annotated[
Literal["json", "plain"],
Parameter(query="type"),
] = "plain",
) -> Response[str] | PairResponse:
pair = await self.get_pair_service.run(
group_uuid=group_uuid,
participant=participant_name,
)
if response_type == "json":
return PairResponse(pair=pair)
return Response(content=pair, media_type=MediaType.TEXT)
config = get_config()
app = Litestar(route_handlers=[GroupController], debug=config.environment == "local")