from repositories.mixins import * from schemas.base_crud import * RepositoryMixin = TypeVar("RepositoryMixin") EntityType = TypeVar("EntityType") SchemaType = TypeVar("SchemaType", bound=BaseSchema) UpdateRequestType = TypeVar("UpdateRequestType", bound=BaseSchema) CreateRequestType = TypeVar("CreateRequestType", bound=BaseSchema) class ServiceBaseMixin(Generic[RepositoryMixin]): repository: RepositoryMixin class ServiceCreateMixin( Generic[EntityType, CreateRequestType, SchemaType], ServiceBaseMixin[RepCreateMixin | RepGetByIdMixin], ): entity_created_msg = "Entity created" schema_class: type[SchemaType] async def create(self, request: CreateRequestType) -> BaseCreateResponse: entity_id = await self.repository.create(request.entity) entity = await self.repository.get_by_id(entity_id) return BaseCreateResponse( entity=self.schema_class.model_validate(entity), message=self.entity_created_msg, ) class ServiceGetAllMixin( Generic[EntityType, SchemaType], ServiceBaseMixin[RepGetAllMixin], ): schema_class: type[SchemaType] async def get_all(self, *args) -> BaseGetAllResponse[SchemaType]: entities = await self.repository.get_all(*args) return BaseGetAllResponse[SchemaType]( items=[self.schema_class.model_validate(entity) for entity in entities] ) class ServiceUpdateMixin( Generic[EntityType, UpdateRequestType], ServiceBaseMixin[RepUpdateMixin | RepGetByIdMixin], ): entity_updated_msg = "Entity updated" async def update( self, entity_id: int, request: UpdateRequestType ) -> BaseUpdateResponse: entity = await self.repository.get_by_id(entity_id) await self.repository.update(entity, request.entity) return BaseUpdateResponse(message=self.entity_updated_msg) class ServiceDeleteMixin( Generic[EntityType], ServiceBaseMixin[RepDeleteMixin | RepGetByIdMixin], ): entity_deleted_msg = "Entity deleted" async def is_soft_delete(self, entity: EntityType) -> bool: return hasattr(entity, "is_deleted") async def delete(self, entity_id: int) -> BaseDeleteResponse: entity = await self.repository.get_by_id(entity_id) is_soft = await self.is_soft_delete(entity) await self.repository.delete(entity, is_soft) return BaseDeleteResponse(message=self.entity_deleted_msg) class ServiceCrudMixin( Generic[EntityType, SchemaType, CreateRequestType, UpdateRequestType], ServiceGetAllMixin[EntityType, SchemaType], ServiceCreateMixin[EntityType, CreateRequestType, SchemaType], ServiceUpdateMixin[EntityType, UpdateRequestType], ServiceDeleteMixin[EntityType], ): pass