from contextlib import asynccontextmanager from typing import AsyncIterator from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.exc import IntegrityError from fooder.repository.user import UserRepository from fooder.repository.product import ProductRepository from fooder.domain import User, Product from fooder.exc import Conflict class Repository: def __init__(self, session: AsyncSession): self.session = session self.user = UserRepository(User, session) self.product = ProductRepository(Product, session) async def commit(self) -> None: try: await self.session.commit() except IntegrityError: raise Conflict() async def rollback(self) -> None: await self.session.rollback() @asynccontextmanager async def transaction(self) -> AsyncIterator["Repository"]: try: yield self await self.commit() except Exception: await self.rollback() raise