remove fucking uow and replace it by TransactionContextManager
parent
12d61e01e1
commit
ad92682eda
|
@ -2,7 +2,7 @@ from fastapi import FastAPI
|
|||
from sqlalchemy.ext.asyncio import (AsyncEngine, AsyncSession,
|
||||
async_sessionmaker)
|
||||
|
||||
from api.application.abstractions.uow import UnitOfWork
|
||||
from api.application.abstractions.transaction import TransactionContextManager
|
||||
from api.application.protocols.date_time import DateTimeProvider
|
||||
from api.application.protocols.jwt import JwtTokenProcessor
|
||||
from api.application.protocols.password_hasher import PasswordHasher
|
||||
|
@ -16,8 +16,8 @@ from api.domain.user.repository import UserRepository
|
|||
from api.infrastructure.auth.jwt_settings import JwtSettings
|
||||
from api.infrastructure.dependencies.adapters import (create_engine,
|
||||
create_session_maker,
|
||||
new_session,
|
||||
new_unit_of_work)
|
||||
get_transaction_context,
|
||||
new_session)
|
||||
from api.infrastructure.dependencies.configs import (app_settings,
|
||||
get_db_settings,
|
||||
get_jwt_settings)
|
||||
|
@ -43,7 +43,7 @@ def init_dependencies(app: FastAPI) -> None:
|
|||
app.dependency_overrides[async_sessionmaker[AsyncSession]] = create_session_maker
|
||||
app.dependency_overrides[AsyncSession] = new_session
|
||||
|
||||
app.dependency_overrides[UnitOfWork] = new_unit_of_work
|
||||
app.dependency_overrides[TransactionContextManager] = get_transaction_context
|
||||
|
||||
app.dependency_overrides[DateTimeProvider] = get_date_time_provider
|
||||
app.dependency_overrides[PasswordHasher] = get_password_hasher
|
||||
|
|
|
@ -2,18 +2,27 @@ from fastapi import FastAPI, Request
|
|||
from fastapi.responses import JSONResponse
|
||||
|
||||
from api.domain.error import DomainValidationError
|
||||
from api.domain.user.error import (
|
||||
UserAlreadyExistsError,
|
||||
from api.domain.user.error import (UserAlreadyExistsError,
|
||||
UserInvalidCredentialsError,
|
||||
UserIsNotAuthorizedError,
|
||||
)
|
||||
UserIsNotAuthorizedError)
|
||||
from api.infrastructure.persistence.error import TransactionContextManagerError
|
||||
|
||||
|
||||
async def validation_error_exc_handler(request: Request, exc: DomainValidationError) -> JSONResponse:
|
||||
async def transaction_error_exec_handler(
|
||||
request: Request, exc: TransactionContextManagerError
|
||||
) -> JSONResponse:
|
||||
return JSONResponse(status_code=400, content={"detail": exc.message})
|
||||
|
||||
|
||||
async def user_authentication_error_exc_handler(request: Request, exc: UserIsNotAuthorizedError) -> JSONResponse:
|
||||
async def validation_error_exc_handler(
|
||||
request: Request, exc: DomainValidationError
|
||||
) -> JSONResponse:
|
||||
return JSONResponse(status_code=400, content={"detail": exc.message})
|
||||
|
||||
|
||||
async def user_authentication_error_exc_handler(
|
||||
request: Request, exc: UserIsNotAuthorizedError
|
||||
) -> JSONResponse:
|
||||
return JSONResponse(
|
||||
status_code=401,
|
||||
content={"detail": exc.message},
|
||||
|
@ -21,7 +30,9 @@ async def user_authentication_error_exc_handler(request: Request, exc: UserIsNot
|
|||
)
|
||||
|
||||
|
||||
async def user_already_exist_error_exc_handler(request: Request, exc: UserAlreadyExistsError) -> JSONResponse:
|
||||
async def user_already_exist_error_exc_handler(
|
||||
request: Request, exc: UserAlreadyExistsError
|
||||
) -> JSONResponse:
|
||||
return JSONResponse(status_code=409, content={"detail": exc.message})
|
||||
|
||||
|
||||
|
@ -36,6 +47,16 @@ def init_exc_handlers(app: FastAPI) -> None:
|
|||
DomainValidationError,
|
||||
validation_error_exc_handler,
|
||||
)
|
||||
app.add_exception_handler(UserIsNotAuthorizedError, user_authentication_error_exc_handler)
|
||||
app.add_exception_handler(UserAlreadyExistsError, user_already_exist_error_exc_handler)
|
||||
app.add_exception_handler(UserInvalidCredentialsError, user_invalid_credentials_error_exc_handler)
|
||||
app.add_exception_handler(
|
||||
UserIsNotAuthorizedError, user_authentication_error_exc_handler
|
||||
)
|
||||
app.add_exception_handler(
|
||||
UserAlreadyExistsError, user_already_exist_error_exc_handler
|
||||
)
|
||||
app.add_exception_handler(
|
||||
UserInvalidCredentialsError, user_invalid_credentials_error_exc_handler
|
||||
)
|
||||
|
||||
app.add_exception_handler(
|
||||
TransactionContextManagerError, transaction_error_exec_handler
|
||||
)
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
from .uow import UnitOfWork
|
||||
|
||||
__all__ = ("UnitOfWork",)
|
|
@ -1,9 +0,0 @@
|
|||
from typing import Protocol
|
||||
|
||||
|
||||
class UnitOfWork(Protocol):
|
||||
async def commit(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
async def rollback(self) -> None:
|
||||
raise NotImplementedError
|
|
@ -1,9 +1,6 @@
|
|||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from api.application.abstractions import UnitOfWork
|
||||
from api.application.abstractions.transaction import TransactionContextManager
|
||||
from api.application.contracts.auth.auth_request import UserCreateRequest
|
||||
from api.application.protocols.password_hasher import PasswordHasher
|
||||
from api.domain.user.error import UserAlreadyExistsError
|
||||
from api.domain.user.model import User
|
||||
from api.domain.user.repository import UserRepository
|
||||
|
||||
|
@ -11,11 +8,11 @@ from api.domain.user.repository import UserRepository
|
|||
class CreateUser:
|
||||
def __init__(
|
||||
self,
|
||||
uow: UnitOfWork,
|
||||
transaction: TransactionContextManager,
|
||||
user_repository: UserRepository,
|
||||
password_hasher: PasswordHasher,
|
||||
) -> None:
|
||||
self.uow = uow
|
||||
self.transaction = transaction
|
||||
self.user_repository = user_repository
|
||||
self.hasher = password_hasher
|
||||
|
||||
|
@ -27,13 +24,6 @@ class CreateUser:
|
|||
hashed_password=self.hasher.hash_password(request.password),
|
||||
)
|
||||
|
||||
try:
|
||||
async with self.transaction as tr:
|
||||
await self.user_repository.create_user(user=user)
|
||||
await self.uow.commit()
|
||||
|
||||
except IntegrityError as e:
|
||||
msg = e.args[0].split("\n")[-1]
|
||||
msg = msg.split(":")[1].strip()
|
||||
|
||||
if "email" in msg:
|
||||
raise UserAlreadyExistsError(message=msg)
|
||||
await tr.commit()
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
from api.application.abstractions.transaction import TransactionContextManager
|
||||
from api.application.contracts.company.company_request import CreateNewCompany
|
||||
from api.application.contracts.company.company_response import CompanyBaseResponse
|
||||
from api.application.contracts.company.company_response import \
|
||||
CompanyBaseResponse
|
||||
from api.domain.company.repository import CompanyRepository
|
||||
|
||||
|
||||
class CreateCompany:
|
||||
def __init__(self, company_repository: CompanyRepository) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
transaction: TransactionContextManager,
|
||||
company_repository: CompanyRepository,
|
||||
) -> None:
|
||||
self.company_repository = company_repository
|
||||
self.transaction = transaction
|
||||
|
||||
async def execute(self, request: CreateNewCompany) -> CompanyBaseResponse:
|
||||
async with self.transaction as tr:
|
||||
# companies = await self.company_repository.
|
||||
return CompanyBaseResponse(name=request.name, email=request.email)
|
||||
|
|
|
@ -1,12 +1,26 @@
|
|||
from api.application.contracts.company.company_request import CompanyByOwnerEmail
|
||||
from api.application.contracts.company.company_response import CompanyBaseResponse
|
||||
from api.application.abstractions.transaction import TransactionContextManager
|
||||
from api.application.contracts.company.company_request import \
|
||||
CompanyByOwnerEmail
|
||||
from api.application.contracts.company.company_response import \
|
||||
CompanyBaseResponse
|
||||
from api.domain.company.repository import CompanyRepository
|
||||
|
||||
|
||||
class GetCompaniesByOwnerEmail:
|
||||
def __init__(self, company_repository: CompanyRepository) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
transaction: TransactionContextManager,
|
||||
company_repository: CompanyRepository,
|
||||
) -> None:
|
||||
self.company_repository = company_repository
|
||||
self.transaction = transaction
|
||||
|
||||
async def execute(self, request: CompanyByOwnerEmail) -> list[CompanyBaseResponse]:
|
||||
companies = await self.company_repository.get_companies_by_owner_email(filter={"email": request.email})
|
||||
return [CompanyBaseResponse(name=comp.name.value, email=comp.email.value) for comp in companies]
|
||||
async with self.transaction:
|
||||
companies = await self.company_repository.get_companies_by_owner_email(
|
||||
filter={"email": request.email}
|
||||
)
|
||||
return [
|
||||
CompanyBaseResponse(name=comp.name.value, email=comp.email.value)
|
||||
for comp in companies
|
||||
]
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
from api.application.abstractions import UnitOfWork
|
||||
from api.application.abstractions.transaction import TransactionContextManager
|
||||
from api.application.contracts.user import GetUserByEmailRequest, UserResponse
|
||||
from api.domain.user.repository import UserRepository
|
||||
|
||||
|
||||
class GetUserByEmail:
|
||||
def __init__(self, uow: UnitOfWork, user_repository: UserRepository) -> None:
|
||||
self.uow = uow
|
||||
def __init__(
|
||||
self, transaction: TransactionContextManager, user_repository: UserRepository
|
||||
) -> None:
|
||||
self.transaction = transaction
|
||||
self.user_repository = user_repository
|
||||
|
||||
async def execute(self, request: GetUserByEmailRequest) -> UserResponse | None:
|
||||
async with self.transaction:
|
||||
user = await self.user_repository.get_user(filter={"email": request.email})
|
||||
if user:
|
||||
return None
|
||||
|
|
|
@ -2,23 +2,20 @@ from collections.abc import AsyncIterable
|
|||
from typing import Annotated
|
||||
|
||||
from fastapi import Depends
|
||||
from sqlalchemy.ext.asyncio import (
|
||||
AsyncEngine,
|
||||
AsyncSession,
|
||||
async_sessionmaker,
|
||||
create_async_engine,
|
||||
)
|
||||
from sqlalchemy.ext.asyncio import (AsyncEngine, AsyncSession,
|
||||
async_sessionmaker, create_async_engine)
|
||||
|
||||
from api.application.abstractions import UnitOfWork
|
||||
from api.application.abstractions.transaction import TransactionContextManager
|
||||
from api.infrastructure.dependencies.stub import Stub
|
||||
from api.infrastructure.persistence.uow import SqlAlchemyUnitOfWork
|
||||
from api.infrastructure.persistence.transaction import \
|
||||
SqlalchemyTransactionContextManager
|
||||
from api.infrastructure.settings import Settings
|
||||
|
||||
|
||||
def new_unit_of_work(
|
||||
session: Annotated[AsyncSession, Depends(Stub(AsyncSession))],
|
||||
) -> UnitOfWork:
|
||||
return SqlAlchemyUnitOfWork(session)
|
||||
def get_transaction_context(
|
||||
session: Annotated[AsyncSession, Depends(Stub(AsyncSession))]
|
||||
) -> TransactionContextManager:
|
||||
return SqlalchemyTransactionContextManager(session)
|
||||
|
||||
|
||||
def create_engine(
|
||||
|
|
|
@ -2,7 +2,7 @@ from typing import Annotated
|
|||
|
||||
from fastapi import Depends
|
||||
|
||||
from api.application.abstractions.uow import UnitOfWork
|
||||
from api.application.abstractions.transaction import TransactionContextManager
|
||||
from api.application.protocols.password_hasher import PasswordHasher
|
||||
from api.application.usecase.auth.create_user import CreateUser
|
||||
from api.application.usecase.company.create_company import CreateCompany
|
||||
|
@ -15,21 +15,33 @@ from api.infrastructure.dependencies.stub import Stub
|
|||
|
||||
def provide_create_user(
|
||||
user_repository: Annotated[UserRepository, Depends(Stub(UserRepository))],
|
||||
uow: Annotated[UnitOfWork, Depends(Stub(UnitOfWork))],
|
||||
transaction: Annotated[
|
||||
TransactionContextManager, Depends(Stub(TransactionContextManager))
|
||||
],
|
||||
password_hasher: Annotated[PasswordHasher, Depends(Stub(PasswordHasher))],
|
||||
) -> CreateUser:
|
||||
return CreateUser(
|
||||
uow=uow, user_repository=user_repository, password_hasher=password_hasher
|
||||
transaction=transaction,
|
||||
user_repository=user_repository,
|
||||
password_hasher=password_hasher,
|
||||
)
|
||||
|
||||
|
||||
def provide_get_companies_by_email(
|
||||
company_repository: Annotated[CompanyRepository, Depends(Stub(CompanyRepository))],
|
||||
transaction: Annotated[
|
||||
TransactionContextManager, Depends(Stub(TransactionContextManager))
|
||||
],
|
||||
) -> GetCompaniesByOwnerEmail:
|
||||
return GetCompaniesByOwnerEmail(company_repository=company_repository)
|
||||
return GetCompaniesByOwnerEmail(
|
||||
transaction=transaction, company_repository=company_repository
|
||||
)
|
||||
|
||||
|
||||
def provide_create_company(
|
||||
company_repository: Annotated[CompanyRepository, Depends(Stub(CompanyRepository))]
|
||||
company_repository: Annotated[CompanyRepository, Depends(Stub(CompanyRepository))],
|
||||
transaction: Annotated[
|
||||
TransactionContextManager, Depends(Stub(TransactionContextManager))
|
||||
],
|
||||
) -> CreateCompany:
|
||||
return CreateCompany(company_repository=company_repository)
|
||||
return CreateCompany(transaction=transaction, company_repository=company_repository)
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from api.application.abstractions import UnitOfWork
|
||||
|
||||
|
||||
class SqlAlchemyUnitOfWork(UnitOfWork):
|
||||
def __init__(self, session: AsyncSession) -> None:
|
||||
self.session = session
|
||||
|
||||
async def commit(self) -> None:
|
||||
await self.session.commit()
|
||||
|
||||
async def rollback(self) -> None:
|
||||
await self.session.rollback()
|
Loading…
Reference in New Issue