Skip to content

Commit

Permalink
feat: decouple job services with proper interface
Browse files Browse the repository at this point in the history
  • Loading branch information
ShahriyarR committed Oct 23, 2022
1 parent c7cbc5a commit 220af22
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 24 deletions.
14 changes: 7 additions & 7 deletions src/jobboard/adapters/entrypoints/api/v1/route_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
get_current_user_from_token,
)
from src.jobboard.domain.model.model import User
from src.jobboard.domain.ports.job_service import JobService
from src.jobboard.domain.ports.use_cases.jobs import JobsServiceInterface
from src.jobboard.domain.ports.responses import ResponseTypes
from src.jobboard.domain.schemas.jobs import JobCreateInputDto
from src.jobboard.configurator.containers import Container
Expand All @@ -25,7 +25,7 @@
def create_job(
job: JobCreateInputDto,
current_user: User = Depends(get_current_user_from_token),
job_service: JobService = Depends(Provide[Container.job_service]),
job_service: JobsServiceInterface = Depends(Provide[Container.job_service]),
):
response = job_service.create(job=job, owner_id=current_user.id)
data = jsonable_encoder(response.value)
Expand All @@ -40,7 +40,7 @@ def create_job(
@inject
def read_job(
id: int,
job_service: JobService = Depends(Provide[Container.job_service]),
job_service: JobsServiceInterface = Depends(Provide[Container.job_service]),
):
response = job_service.retrieve_job(id_=id)
data = jsonable_encoder(response.value)
Expand All @@ -54,7 +54,7 @@ def read_job(
@router.get("/all")
@inject
def read_jobs(
job_service: JobService = Depends(Provide[Container.job_service]),
job_service: JobsServiceInterface = Depends(Provide[Container.job_service]),
):
response = job_service.list_jobs()
data = jsonable_encoder(response.value)
Expand All @@ -71,7 +71,7 @@ def update_job(
id: int,
job: JobCreateInputDto,
current_user: User = Depends(get_current_user_from_token),
job_service: JobService = Depends(Provide[Container.job_service]),
job_service: JobsServiceInterface = Depends(Provide[Container.job_service]),
):
response = job_service.update_job_by_id(id_=id, job=job, owner_id=current_user.id)
data = jsonable_encoder(response.value)
Expand All @@ -87,7 +87,7 @@ def update_job(
def delete_job(
id: int,
current_user: User = Depends(get_current_user_from_token),
job_service: JobService = Depends(Provide[Container.job_service]),
job_service: JobsServiceInterface = Depends(Provide[Container.job_service]),
):
response = job_service.retrieve_job(id_=id)
if response.type != ResponseTypes.SUCCESS:
Expand All @@ -112,7 +112,7 @@ def delete_job(
@inject
def autocomplete(
term: Optional[str] = None,
job_service: JobService = Depends(Provide[Container.job_service]),
job_service: JobsServiceInterface = Depends(Provide[Container.job_service]),
):
jobs = job_service.search_job(term)
return [job.title for job in jobs]
12 changes: 6 additions & 6 deletions src/jobboard/adapters/entrypoints/webapps/jobs/route_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
)
from src.jobboard.adapters.entrypoints.webapps.jobs.forms import JobCreateForm
from src.jobboard.domain.model.model import User
from src.jobboard.domain.ports.job_service import JobService
from src.jobboard.domain.ports.use_cases.jobs import JobsServiceInterface
from src.jobboard.domain.schemas.jobs import JobCreateInputDto
from src.jobboard.configurator.containers import Container

Expand All @@ -22,7 +22,7 @@
@inject
async def home(
request: Request,
job_service: JobService = Depends(Provide[Container.job_service]),
job_service: JobsServiceInterface = Depends(Provide[Container.job_service]),
msg: Optional[str] = None,
):
jobs = job_service.list_jobs()
Expand All @@ -36,7 +36,7 @@ async def home(
def job_detail(
id: int,
request: Request,
job_service: JobService = Depends(Provide[Container.job_service]),
job_service: JobsServiceInterface = Depends(Provide[Container.job_service]),
):
job = job_service.retrieve_job(id_=id)
return templates.TemplateResponse(
Expand All @@ -53,7 +53,7 @@ def create_job(request: Request):
@inject
async def create_job(
request: Request,
job_service: JobService = Depends(Provide[Container.job_service]),
job_service: JobsServiceInterface = Depends(Provide[Container.job_service]),
):
form = JobCreateForm(request)
await form.load_data()
Expand Down Expand Up @@ -81,7 +81,7 @@ async def create_job(
@router.get("/delete-job/")
@inject
def show_jobs_to_delete(
request: Request, job_service: JobService = Depends(Provide[Container.job_service])
request: Request, job_service: JobsServiceInterface = Depends(Provide[Container.job_service])
):
jobs = job_service.list_jobs()
return templates.TemplateResponse(
Expand All @@ -93,7 +93,7 @@ def show_jobs_to_delete(
@inject
def search(
request: Request,
job_service: JobService = Depends(Provide[Container.job_service]),
job_service: JobsServiceInterface = Depends(Provide[Container.job_service]),
query: Optional[str] = None,
):
jobs = job_service.search_job(query)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
ResponseTypes,
)
from src.jobboard.domain.ports.unit_of_work import JobUnitOfWorkInterface
from src.jobboard.domain.ports.use_cases.jobs import JobsServiceInterface
from src.jobboard.domain.schemas.jobs import JobCreateInputDto, JobOutputDto


Expand All @@ -26,11 +27,11 @@ def _handle_response_failure(
)


class JobService:
class JobsService(JobsServiceInterface):
def __init__(self, uow: JobUnitOfWorkInterface):
self.uow = uow

def create(
def _create(
self, job: JobCreateInputDto, owner_id: int
) -> Union[ResponseFailure, ResponseSuccess]:
try:
Expand All @@ -50,7 +51,7 @@ def create(
except Exception as exc:
return ResponseFailure(ResponseTypes.SYSTEM_ERROR, exc)

def retrieve_job(self, id_: int) -> Union[ResponseFailure, ResponseSuccess]:
def _retrieve_job(self, id_: int) -> Union[ResponseFailure, ResponseSuccess]:
with self.uow:
job = self.uow.jobs.get(id_)
return (
Expand All @@ -59,12 +60,12 @@ def retrieve_job(self, id_: int) -> Union[ResponseFailure, ResponseSuccess]:
else _handle_response_failure(id_)
)

def list_jobs(self) -> ResponseSuccess:
def _list_jobs(self) -> ResponseSuccess:
with self.uow:
jobs = self.uow.jobs.get_all()
return ResponseSuccess([JobOutputDto.from_orm(job) for job in jobs])

def update_job_by_id(
def _update_job_by_id(
self, id_: int, job: JobCreateInputDto, owner_id: int
) -> Union[ResponseFailure, ResponseSuccess]:
with self.uow:
Expand All @@ -77,7 +78,7 @@ def update_job_by_id(
job_ = self.uow.jobs.get(id_)
return ResponseSuccess(JobOutputDto.from_orm(job_))

def delete_job_by_id(self, id_: int) -> Union[ResponseFailure, ResponseSuccess]:
def _delete_job_by_id(self, id_: int) -> Union[ResponseFailure, ResponseSuccess]:
with self.uow:
existing_job = self.uow.jobs.get(id_)
if not existing_job:
Expand All @@ -86,7 +87,7 @@ def delete_job_by_id(self, id_: int) -> Union[ResponseFailure, ResponseSuccess]:
self.uow.commit()
return ResponseSuccess(value={"detail": "Successfully deleted."})

def search_job(self, query: str) -> ResponseSuccess:
def _search_job(self, query: str) -> ResponseSuccess:
with self.uow:
result = self.uow.jobs.search(query)
return ResponseSuccess(value=result)
4 changes: 2 additions & 2 deletions src/jobboard/configurator/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
JobSqlAlchemyUnitOfWork,
UserSqlAlchemyUnitOfWork,
)
from src.jobboard.domain.ports.job_service import JobService
from src.jobboard.adapters.use_cases.jobs import JobsService
from src.jobboard.domain.ports.user_service import UserService
from src.jobboard.configurator import config

Expand Down Expand Up @@ -39,4 +39,4 @@ class Container(containers.DeclarativeContainer):
uow=user_uow,
)

job_service = providers.Factory(JobService, uow=job_uow)
job_service = providers.Factory(JobsService, uow=job_uow)
63 changes: 63 additions & 0 deletions src/jobboard/domain/ports/use_cases/jobs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import abc
from typing import Union

from src.jobboard.domain.ports.responses import ResponseFailure, ResponseSuccess
from src.jobboard.domain.ports.unit_of_work import JobUnitOfWorkInterface
from src.jobboard.domain.schemas.jobs import JobCreateInputDto


class JobsServiceInterface(abc.ABC):

@abc.abstractmethod
def __init__(self, uow: JobUnitOfWorkInterface):
self.uow = uow

def create(
self, job: JobCreateInputDto, owner_id: int
) -> Union[ResponseFailure, ResponseSuccess]:
return self._create(job, owner_id)

def retrieve_job(self, id_: int) -> Union[ResponseFailure, ResponseSuccess]:
return self._retrieve_job(id_)

def list_jobs(self) -> ResponseSuccess:
return self._list_jobs()

def update_job_by_id(
self, id_: int, job: JobCreateInputDto, owner_id: int
) -> Union[ResponseFailure, ResponseSuccess]:
return self._update_job_by_id(id_, job, owner_id)

def delete_job_by_id(self, id_: int) -> Union[ResponseFailure, ResponseSuccess]:
return self._delete_job_by_id(id_)

def search_job(self, query: str) -> ResponseSuccess:
return self._search_job(query)

@abc.abstractmethod
def _create(
self, job: JobCreateInputDto, owner_id: int
) -> Union[ResponseFailure, ResponseSuccess]:
raise NotImplementedError

@abc.abstractmethod
def _retrieve_job(self, id_: int) -> Union[ResponseFailure, ResponseSuccess]:
raise NotImplementedError

@abc.abstractmethod
def _list_jobs(self) -> ResponseSuccess:
raise NotImplementedError

@abc.abstractmethod
def _update_job_by_id(
self, id_: int, job: JobCreateInputDto, owner_id: int
) -> Union[ResponseFailure, ResponseSuccess]:
raise NotImplementedError

@abc.abstractmethod
def _delete_job_by_id(self, id_: int) -> Union[ResponseFailure, ResponseSuccess]:
raise NotImplementedError

@abc.abstractmethod
def _search_job(self, query: str) -> ResponseSuccess:
raise NotImplementedError
Empty file.
4 changes: 2 additions & 2 deletions tests/fake_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
JobSqlAlchemyUnitOfWork,
UserSqlAlchemyUnitOfWork,
)
from src.jobboard.domain.ports.job_service import JobService
from src.jobboard.adapters.use_cases.jobs import JobsService
from src.jobboard.domain.ports.user_service import UserService


Expand Down Expand Up @@ -39,4 +39,4 @@ class Container(containers.DeclarativeContainer):
uow=user_uow,
)

fake_job_service = providers.Factory(JobService, uow=job_uow)
fake_job_service = providers.Factory(JobsService, uow=job_uow)

0 comments on commit 220af22

Please sign in to comment.