Coverage for kwai/api/v1/trainings/endpoints/trainings.py: 90%
71 statements
« prev ^ index » next coverage.py v7.3.0, created at 2023-09-05 17:55 +0000
« prev ^ index » next coverage.py v7.3.0, created at 2023-09-05 17:55 +0000
1"""Module for endpoints for trainings."""
2from datetime import datetime
4from fastapi import APIRouter, Depends, HTTPException, Query, status
5from pydantic import BaseModel, Field
7from kwai.api.dependencies import deps, get_current_user
8from kwai.api.v1.trainings.schemas.training import TrainingResource
9from kwai.core.db.database import Database
10from kwai.core.domain.value_objects.owner import Owner
11from kwai.core.json_api import Meta, PaginationModel
12from kwai.modules.identity.users.user import UserEntity
13from kwai.modules.training.coaches.coach_db_repository import CoachDbRepository
14from kwai.modules.training.coaches.coach_repository import CoachNotFoundException
15from kwai.modules.training.create_training import (
16 CreateTraining,
17 CreateTrainingCommand,
18)
19from kwai.modules.training.delete_training import DeleteTraining, DeleteTrainingCommand
20from kwai.modules.training.get_training import GetTraining, GetTrainingCommand
21from kwai.modules.training.get_trainings import GetTrainings, GetTrainingsCommand
22from kwai.modules.training.teams.team_db_repository import TeamDbRepository
23from kwai.modules.training.training_command import Coach
24from kwai.modules.training.trainings.training_db_repository import TrainingDbRepository
25from kwai.modules.training.trainings.training_definition_db_repository import (
26 TrainingDefinitionDbRepository,
27)
28from kwai.modules.training.trainings.training_definition_repository import (
29 TrainingDefinitionNotFoundException,
30)
31from kwai.modules.training.trainings.training_repository import (
32 TrainingNotFoundException,
33)
34from kwai.modules.training.update_training import UpdateTraining, UpdateTrainingCommand
36router = APIRouter()
39class TrainingsFilterModel(BaseModel):
40 """Define the JSON:API filter for trainings."""
42 year: int | None = Field(Query(default=None, alias="filter[year]"))
43 month: int | None = Field(Query(default=None, alias="filter[month]"))
44 start: datetime | None = Field(Query(default=None, alias="filter[start]"))
45 end: datetime | None = Field(Query(default=None, alias="filter[end]"))
46 active: bool = Field(Query(default=True, alias="filter[active]"))
47 coach: int | None = Field(Query(default=None, alias="filter[coach]"))
48 definition: int | None = Field(Query(default=None, alias="filter[definition]"))
51@router.get(
52 "/trainings",
53 responses={
54 status.HTTP_404_NOT_FOUND: {
55 "description": "Coach or Training definition was not found."
56 }
57 },
58)
59async def get_trainings(
60 pagination: PaginationModel = Depends(PaginationModel),
61 trainings_filter: TrainingsFilterModel = Depends(TrainingsFilterModel),
62 db=deps.depends(Database),
63) -> TrainingResource.get_document_model():
64 """Get all trainings."""
65 command = GetTrainingsCommand(
66 offset=pagination.offset or 0,
67 limit=pagination.limit,
68 year=trainings_filter.year,
69 month=trainings_filter.month,
70 start=trainings_filter.start,
71 end=trainings_filter.end,
72 active=trainings_filter.active,
73 coach=trainings_filter.coach,
74 definition=trainings_filter.definition,
75 )
77 try:
78 count, training_iterator = await GetTrainings(
79 TrainingDbRepository(db),
80 CoachDbRepository(db),
81 TrainingDefinitionDbRepository(db),
82 ).execute(command)
83 except TrainingDefinitionNotFoundException as ex:
84 raise HTTPException(
85 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex)
86 ) from ex
87 except CoachNotFoundException as ex:
88 raise HTTPException(
89 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex)
90 ) from ex
92 document = TrainingResource.serialize_list(
93 [TrainingResource(training) async for training in training_iterator]
94 )
95 document.meta = Meta(count=count, offset=command.offset, limit=command.limit)
97 return document
100@router.get(
101 "/trainings/{training_id}",
102 responses={status.HTTP_404_NOT_FOUND: {"description": "Training was not found."}},
103)
104async def get_training(
105 training_id: int,
106 db=deps.depends(Database),
107) -> TrainingResource.get_document_model():
108 """Get the training with the given id."""
109 command = GetTrainingCommand(id=training_id)
111 try:
112 training = await GetTraining(TrainingDbRepository(db)).execute(command)
113 except TrainingNotFoundException as ex:
114 raise HTTPException(
115 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex)
116 ) from ex
118 return TrainingResource.serialize(TrainingResource(training))
121@router.post(
122 "/trainings",
123 status_code=status.HTTP_201_CREATED,
124)
125async def create_training(
126 resource: TrainingResource.get_resource_data_model(),
127 db=deps.depends(Database),
128 user: UserEntity = Depends(get_current_user),
129) -> TrainingResource.get_document_model():
130 """Create a new training."""
131 command = CreateTrainingCommand(
132 start_date=resource.data.attributes.event.start_date,
133 end_date=resource.data.attributes.event.end_date,
134 active=resource.data.attributes.event.active,
135 cancelled=resource.data.attributes.event.cancelled,
136 text=[
137 {
138 "locale": text.locale,
139 "format": text.format,
140 "title": text.title,
141 "summary": text.summary,
142 "content": text.content,
143 }
144 for text in resource.data.attributes.contents
145 ],
146 coaches=[
147 Coach(
148 id=int(coach.id),
149 head=coach.head,
150 present=coach.present,
151 payed=coach.payed,
152 )
153 for coach in resource.data.attributes.coaches
154 ],
155 teams=[int(team.id) for team in resource.data.relationships.teams.data],
156 definition=None,
157 location=resource.data.attributes.event.location,
158 remark=resource.data.attributes.remark,
159 )
161 try:
162 resource = await CreateTraining(
163 TrainingDbRepository(db),
164 TrainingDefinitionDbRepository(db),
165 CoachDbRepository(db),
166 TeamDbRepository(db),
167 Owner(id=user.id, uuid=user.uuid, name=user.name),
168 ).execute(command)
169 except ValueError as ve:
170 raise HTTPException(
171 status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(ve)
172 ) from ve
174 return TrainingResource.serialize(TrainingResource(resource))
177@router.patch(
178 "/trainings/{training_id}",
179 responses={status.HTTP_404_NOT_FOUND: {"description": "Training was not found."}},
180)
181async def update_training(
182 training_id: int,
183 resource: TrainingResource.get_resource_data_model(),
184 db=deps.depends(Database),
185 user: UserEntity = Depends(get_current_user),
186) -> TrainingResource.get_document_model():
187 """Update a training."""
188 command = UpdateTrainingCommand(
189 id=training_id,
190 start_date=resource.data.attributes.event.start_date,
191 end_date=resource.data.attributes.event.end_date,
192 active=resource.data.attributes.event.active,
193 cancelled=resource.data.attributes.event.cancelled,
194 text=[
195 {
196 "locale": text.locale,
197 "format": text.format,
198 "title": text.title,
199 "summary": text.summary,
200 "content": text.content,
201 }
202 for text in resource.data.attributes.contents
203 ],
204 coaches=[
205 Coach(
206 id=int(coach.id),
207 head=coach.head,
208 present=coach.present,
209 payed=coach.payed,
210 )
211 for coach in resource.data.attributes.coaches
212 ],
213 teams=[int(team.id) for team in resource.data.relationships.teams.data],
214 definition=None,
215 location=resource.data.attributes.event.location,
216 remark=resource.data.attributes.remark,
217 )
219 try:
220 resource = await UpdateTraining(
221 TrainingDbRepository(db),
222 TrainingDefinitionDbRepository(db),
223 CoachDbRepository(db),
224 TeamDbRepository(db),
225 Owner(id=user.id, uuid=user.uuid, name=user.name),
226 ).execute(command)
227 except ValueError as ve:
228 raise HTTPException(
229 status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(ve)
230 ) from ve
232 return TrainingResource.serialize(TrainingResource(resource))
235@router.delete(
236 "/trainings/{training_id}",
237 responses={status.HTTP_404_NOT_FOUND: {"description": "Training was not found."}},
238)
239async def delete_training_definition(
240 training_definition_id: int,
241 resource: TrainingResource.get_resource_data_model(),
242 db=deps.depends(Database),
243 user: UserEntity = Depends(get_current_user),
244) -> None:
245 """Delete a training definition."""
246 command = DeleteTrainingCommand(id=training_definition_id)
247 await DeleteTraining(TrainingDbRepository(db)).execute(command)