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
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
exclude = .git,__pycache__, *env,.venv,*venv,migrations,logs,src/app/interfaces/grpc
max-line-length = 115
max-complexity = 8
# E203: whitespace before ':' - conflicts with Black formatter
extend-ignore = E203
1,165 changes: 1,165 additions & 0 deletions docs/source/ddd_concepts.rst

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ Welcome to documentation!
base_commands
env_variables
db_structure
ddd_concepts
Empty file.
8 changes: 8 additions & 0 deletions src/app/application/common/dto/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from dataclasses import dataclass

from src.app.application.common.services.base import BaseSvcOutEntity


@dataclass
class AppBaseDTO(BaseSvcOutEntity):
pass
147 changes: 111 additions & 36 deletions src/app/application/common/services/base.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
from abc import ABC
from typing import Any, Dict, Generic, List, Optional, Tuple, Type
from dataclasses import dataclass
from typing import Any, Dict, Generic, List, Optional, Tuple, Type, TypeVar

from src.app.infrastructure.repositories.base.abstract import AbstractBaseRepository, OuterGenericType
from src.app.infrastructure.repositories.base.abstract import AbstractBaseRepository, BaseOutEntity


@dataclass
class BaseSvcOutEntity(BaseOutEntity):
pass


OutSvcGenericType = TypeVar("OutSvcGenericType", bound=BaseSvcOutEntity)


class AbstractBaseApplicationService(ABC):
pass


class AbstractApplicationService(AbstractBaseApplicationService, Generic[OuterGenericType]):
class AbstractApplicationService(AbstractBaseApplicationService, Generic[OutSvcGenericType]):
@classmethod
async def count(cls, filter_data: dict) -> int:
raise NotImplementedError
Expand All @@ -18,41 +27,69 @@ async def is_exists(cls, filter_data: dict) -> bool:
raise NotImplementedError

@classmethod
async def get_first(cls, filter_data: dict) -> OuterGenericType | None:
async def get_first(
cls,
filter_data: dict,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> OutSvcGenericType | None:
raise NotImplementedError

@classmethod
async def get_list(
cls, filter_data: dict, offset: int = 0, limit: Optional[int] = None, order_data: Tuple[str] = ("id",)
) -> List[OuterGenericType]:
cls,
filter_data: dict,
offset: int = 0,
limit: Optional[int] = None,
order_data: Tuple[str] = ("id",),
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> List[OutSvcGenericType]:
raise NotImplementedError

@classmethod
async def create(cls, data: dict, is_return_require: bool = False) -> OuterGenericType | None:
async def create(
cls,
data: dict,
is_return_require: bool = False,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> OutSvcGenericType | None:
raise NotImplementedError

@classmethod
async def create_bulk(
cls, items: List[dict], is_return_require: bool = False
) -> List[OuterGenericType] | None:
cls,
items: List[dict],
is_return_require: bool = False,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> List[OutSvcGenericType] | None:
raise NotImplementedError

@classmethod
async def update(
cls, filter_data: dict, data: Dict[str, Any], is_return_require: bool = False
) -> OuterGenericType | None:
cls,
filter_data: dict,
data: Dict[str, Any],
is_return_require: bool = False,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> OutSvcGenericType | None:
raise NotImplementedError

@classmethod
async def update_bulk(
cls, items: List[dict], is_return_require: bool = False
) -> List[OuterGenericType] | None:
cls,
items: List[dict],
is_return_require: bool = False,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> List[OutSvcGenericType] | None:
raise NotImplementedError

@classmethod
async def update_or_create(
cls, filter_data: dict, data: Dict[str, Any], is_return_require: bool = False
) -> OuterGenericType | None:
cls,
filter_data: dict,
data: Dict[str, Any],
is_return_require: bool = False,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> OutSvcGenericType | None:
raise NotImplementedError

@classmethod
Expand All @@ -63,8 +100,8 @@ async def remove(
raise NotImplementedError


class BaseApplicationService(AbstractApplicationService[OuterGenericType], Generic[OuterGenericType]):
repository: Type[AbstractBaseRepository[OuterGenericType]]
class BaseApplicationService(AbstractApplicationService[OutSvcGenericType], Generic[OutSvcGenericType]):
repository: Type[AbstractBaseRepository[OutSvcGenericType]]

@classmethod
async def count(cls, filter_data: dict) -> int:
Expand All @@ -75,48 +112,86 @@ async def is_exists(cls, filter_data: dict) -> bool:
return await cls.repository.is_exists(filter_data=filter_data)

@classmethod
async def get_first(cls, filter_data: dict) -> OuterGenericType | None:
item = await cls.repository.get_first(filter_data=filter_data)
async def get_first(
cls,
filter_data: dict,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> OutSvcGenericType | None:
item = await cls.repository.get_first(filter_data=filter_data, out_dataclass=out_dataclass)
return item

@classmethod
async def get_list(
cls, filter_data: dict, offset: int = 0, limit: Optional[int] = None, order_data: Tuple[str] = ("id",)
) -> List[OuterGenericType]:
cls,
filter_data: dict,
offset: int = 0,
limit: Optional[int] = None,
order_data: Tuple[str] = ("id",),
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> List[OutSvcGenericType]:
filter_data_ = filter_data.copy()
filter_data_["offset"] = offset
if limit is not None:
filter_data_["limit"] = limit
return await cls.repository.get_list(filter_data=filter_data_, order_data=order_data)
return await cls.repository.get_list(
filter_data=filter_data_, order_data=order_data, out_dataclass=out_dataclass
)

@classmethod
async def create(cls, data: dict, is_return_require: bool = False) -> OuterGenericType | None:
return await cls.repository.create(data=data, is_return_require=is_return_require)
async def create(
cls,
data: dict,
is_return_require: bool = False,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> OutSvcGenericType | None:
return await cls.repository.create(
data=data, is_return_require=is_return_require, out_dataclass=out_dataclass
)

@classmethod
async def create_bulk(
cls, items: List[dict], is_return_require: bool = False
) -> List[OuterGenericType] | None:
return await cls.repository.create_bulk(items=items, is_return_require=is_return_require)
cls,
items: List[dict],
is_return_require: bool = False,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> List[OutSvcGenericType] | None:
return await cls.repository.create_bulk(
items=items, is_return_require=is_return_require, out_dataclass=out_dataclass
)

@classmethod
async def update(
cls, filter_data: dict, data: Dict[str, Any], is_return_require: bool = False
) -> OuterGenericType | None:
return await cls.repository.update(filter_data=filter_data, data=data, is_return_require=is_return_require)
cls,
filter_data: dict,
data: Dict[str, Any],
is_return_require: bool = False,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> OutSvcGenericType | None:
return await cls.repository.update(
filter_data=filter_data, data=data, is_return_require=is_return_require, out_dataclass=out_dataclass
)

@classmethod
async def update_bulk(
cls, items: List[dict], is_return_require: bool = False
) -> List[OuterGenericType] | None:
return await cls.repository.update_bulk(items=items, is_return_require=is_return_require)
cls,
items: List[dict],
is_return_require: bool = False,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> List[OutSvcGenericType] | None:
return await cls.repository.update_bulk(
items=items, is_return_require=is_return_require, out_dataclass=out_dataclass
)

@classmethod
async def update_or_create(
cls, filter_data: dict, data: Dict[str, Any], is_return_require: bool = False
) -> OuterGenericType | None:
cls,
filter_data: dict,
data: Dict[str, Any],
is_return_require: bool = False,
out_dataclass: Optional[Type[OutSvcGenericType]] = None,
) -> OutSvcGenericType | None:
return await cls.repository.update_or_create(
filter_data=filter_data, data=data, is_return_require=is_return_require
filter_data=filter_data, data=data, is_return_require=is_return_require, out_dataclass=out_dataclass
)

@classmethod
Expand Down
18 changes: 9 additions & 9 deletions src/app/application/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@

class ApplicationServicesContainer:
@property
def users_service(self) -> Type["src.app.application.services.users_service.UserService"]:
from src.app.application.services.users_service import UserService
def users_service(self) -> Type["src.app.application.services.users_service.AppUserService"]:
from src.app.application.services.users_service import AppUserService

return UserService
return AppUserService

@property
def auth_service(self) -> Type["src.app.application.services.auth_service.AuthService"]:
from src.app.application.services.auth_service import AuthService
def auth_service(self) -> Type["src.app.application.services.auth_service.AppAuthService"]:
from src.app.application.services.auth_service import AppAuthService

return AuthService
return AppAuthService

@property
def common_service(self) -> Type["src.app.application.services.common_service.CommonApplicationService"]:
from src.app.application.services.common_service import CommonApplicationService
def common_service(self) -> Type["src.app.application.services.common_service.AppCommonService"]:
from src.app.application.services.common_service import AppCommonService

return CommonApplicationService
return AppCommonService


container = ApplicationServicesContainer()
Empty file.
17 changes: 17 additions & 0 deletions src/app/application/dto/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from dataclasses import dataclass
from typing import Optional

from uuid import UUID

from src.app.application.common.dto.base import AppBaseDTO


@dataclass
class UserShortDTO(AppBaseDTO):
id: int
uuid: UUID
first_name: Optional[str]
last_name: Optional[str]
email: Optional[str]
phone: Optional[str]
is_active: bool
Loading