import random from abc import ABC, abstractmethod from typing import Any from pydantic import UUID4, BaseModel from secretsanta.settings import Config, get_config class Group(BaseModel): uuid: UUID4 participants: list[str] pairs: dict[str, str] | None = None @staticmethod def pair(names: list[str]) -> dict[str, str]: names_copy = names[:] random.shuffle(names_copy) pairings = {} for i, name in enumerate(names): pair = names_copy[i] while pair == name: random.shuffle(names_copy) pair = names_copy[i] pairings[name] = pair return pairings class IRepo(ABC): @abstractmethod async def get(self, group_uuid: str) -> Group | None: ... # pragma: no cover @abstractmethod async def create(self, group: Group) -> Group: ... # pragma: no cover class IService(ABC): def __init__(self, repo: IRepo, config: Config | None = None): self.repo = repo self.config = config or get_config() @abstractmethod async def run(self, *args, **kwargs) -> Any: ... # pragma: no cover