Skip to content

Commit

Permalink
chore: api routes for user check-ins and workshop check-ins created
Browse files Browse the repository at this point in the history
  • Loading branch information
fivan999 committed Nov 1, 2024
1 parent 07c4304 commit cb26256
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

###########################################################
# Base Python image. Set shared environment variables.
FROM python:3.13-slim-bullseye AS base
FROM python:3.12-slim-bullseye AS base
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
Expand Down
4 changes: 2 additions & 2 deletions src/api/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
VERSION = "0.1.0"

# Info for OpenAPI specification
TITLE = "FastAPI template"
SUMMARY = "FastAPI template for InNoHassle ecosystem."
TITLE = "Workshops API"
SUMMARY = "Workshops API | InNoHassle ecosystem for InNoHassle ecosystem."

DESCRIPTION = None

Expand Down
31 changes: 23 additions & 8 deletions src/modules/workshops/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.ext.asyncio import AsyncSession

from src.modules.users.schemes import ViewUserScheme
from src.modules.workshops.schemes import CreateWorkshopScheme, ViewWorkshopScheme
from src.storages.sql.models.users import User
from src.storages.sql.models.workshops import CheckIn, Workshop


Expand All @@ -26,12 +28,6 @@ async def read_all(self) -> list[ViewWorkshopScheme]:
workshops = workshops.scalars()
return [ViewWorkshopScheme.model_validate(wk, from_attributes=True) for wk in workshops]

async def get_list_by_user_id(self, user_id: int) -> list[ViewWorkshopScheme]:
request = select(Workshop).join(Workshop.check_ins).where(CheckIn.user_id == user_id)
workshops = await self.session.execute(request)
workshops = workshops.scalars()
return [ViewWorkshopScheme.model_validate(wk, from_attributes=True) for wk in workshops]

async def get_by_id(self, workshop_id: int) -> ViewWorkshopScheme | None:
request = select(Workshop).where(Workshop.id == workshop_id)
workshop = await self.session.execute(request)
Expand All @@ -40,12 +36,12 @@ async def get_by_id(self, workshop_id: int) -> ViewWorkshopScheme | None:
return ViewWorkshopScheme.model_validate(workshop, from_attributes=True)

async def update_remain_places(self, workshop_id: int, delta: int) -> None:
request = (
query = (
update(Workshop)
.where(Workshop.id == workshop_id)
.values({Workshop.remain_places: Workshop.remain_places + delta})
)
await self.session.execute(request)
await self.session.execute(query)


class SqlCheckInRepository:
Expand Down Expand Up @@ -86,3 +82,22 @@ async def delete(self, workshop_id: int, user_id: int) -> bool:
await self.session.commit()

return True

async def get_check_inned_users_by_workshop_id(self, workshop_id: int) -> list[ViewUserScheme] | None:
workshop = await self.workshops_repository.get_by_id(workshop_id)
if workshop is None:
return
query = select(CheckIn, User).join(User, User.id == CheckIn.user_id).where(CheckIn.workshop_id == workshop_id)
results = await self.session.execute(query)
results = results.all()
return [ViewUserScheme.model_validate(user, from_attributes=True) for _, user in results]

async def get_check_inned_workshops_by_user_id(self, user_id: int) -> list[ViewWorkshopScheme]:
query = (
select(CheckIn, Workshop)
.join(Workshop, Workshop.id == CheckIn.workshop_id)
.where(CheckIn.user_id == user_id)
)
results = await self.session.execute(query)
results = results.all()
return [ViewWorkshopScheme.model_validate(wk, from_attributes=True) for _, wk in results]
43 changes: 37 additions & 6 deletions src/modules/workshops/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from src.api.dependencies import CurrentUserIdDep
from src.api.exceptions import IncorrectCredentialsException
from src.modules.users.schemes import ViewUserScheme
from src.modules.workshops.dependencies import SqlCheckInRepositoryDep, SqlWorkshopRepositoryDep
from src.modules.workshops.schemes import CreateWorkshopScheme, ViewWorkshopScheme

Expand Down Expand Up @@ -42,6 +43,19 @@ async def create_workshop(
return Response(status_code=status.HTTP_400_BAD_REQUEST)


@router.get(
"/my-check-ins",
status_code=status.HTTP_200_OK,
responses={
status.HTTP_200_OK: {"description": "List of workshops"},
},
)
async def get_my_check_ins(
user_id: CurrentUserIdDep, check_in_repository: SqlCheckInRepositoryDep
) -> list[ViewWorkshopScheme]:
return await check_in_repository.get_check_inned_workshops_by_user_id(user_id)


@router.post(
"/check-in/{workshop_id}",
status_code=status.HTTP_200_OK,
Expand Down Expand Up @@ -77,13 +91,30 @@ async def check_out_workshop(


@router.get(
"/my-check-ins",
"/{workshop_id}",
status_code=status.HTTP_200_OK,
responses={
status.HTTP_200_OK: {"description": "List of workshops", "model": ViewWorkshopScheme},
status.HTTP_200_OK: {"description": "Workshop information"},
status.HTTP_404_NOT_FOUND: {"description": "Workshop is not found"},
},
)
async def get_my_check_ins(
user_id: CurrentUserIdDep, workshops_repository: SqlWorkshopRepositoryDep
) -> list[ViewWorkshopScheme]:
return await workshops_repository.get_list_by_user_id(user_id)
async def read_workshop_by_id(workshop_repository: SqlWorkshopRepositoryDep, workshop_id: int) -> ViewWorkshopScheme:
workshop = await workshop_repository.get_by_id(workshop_id)
if workshop:
return workshop
return Response(status_code=status.HTTP_404_NOT_FOUND)


@router.get(
"/{workshop_id}/check-ins",
status_code=status.HTTP_200_OK,
responses={
status.HTTP_200_OK: {"description": "List of users"},
status.HTTP_404_NOT_FOUND: {"description": "Workshop is not found"},
},
)
async def read_check_in_users(check_in_repository: SqlCheckInRepositoryDep, workshop_id: int) -> list[ViewUserScheme]:
users = await check_in_repository.get_check_inned_users_by_workshop_id(workshop_id)
if users is None:
return Response(status_code=status.HTTP_404_NOT_FOUND)
return users
6 changes: 6 additions & 0 deletions src/modules/workshops/schemes.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,9 @@ def order_times(self):
if self.dtstart >= self.dtend:
raise ValueError("`dtstart` must be less than `dtend`")
return self

@model_validator(mode="after")
def validate_capacity(self):
if self.capacity <= 0:
raise ValueError("`capacity` must be greater than zero")
return self
2 changes: 1 addition & 1 deletion src/storages/sql/models/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ class User(Base):
"User's name"
role: Mapped[UserRole] = mapped_column(Enum(UserRole), default=UserRole.DEFAULT)
"User's role"
check_ins = relationship("CheckIn", back_populates="user")
check_ins = relationship("CheckIn", back_populates="user", lazy="selectin")
2 changes: 1 addition & 1 deletion src/storages/sql/models/workshops.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Workshop(Base):
capacity: Mapped[int] = mapped_column()
remain_places: Mapped[int] = mapped_column()

check_ins = relationship("CheckIn", back_populates="workshop")
check_ins = relationship("CheckIn", back_populates="workshop", lazy="selectin")


class CheckIn(Base):
Expand Down

0 comments on commit cb26256

Please sign in to comment.