Coverage for src/kwai/api/v1/trainings/endpoints/training_definitions.py: 81%

78 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2024-01-01 00:00 +0000

1"""Module for endpoints for training definitions.""" 

2 

3from fastapi import APIRouter, Depends, HTTPException, status 

4 

5from kwai.api.dependencies import create_database, get_current_user 

6from kwai.api.v1.trainings.endpoints.trainings import TrainingsFilterModel 

7from kwai.api.v1.trainings.schemas.training import TrainingDocument 

8from kwai.api.v1.trainings.schemas.training_definition import ( 

9 TrainingDefinitionDocument, 

10) 

11from kwai.core.domain.value_objects.owner import Owner 

12from kwai.core.json_api import Meta, PaginationModel 

13from kwai.modules.identity.users.user import UserEntity 

14from kwai.modules.training.coaches.coach_db_repository import CoachDbRepository 

15from kwai.modules.training.coaches.coach_repository import CoachNotFoundException 

16from kwai.modules.training.create_training_definition import ( 

17 CreateTrainingDefinition, 

18 CreateTrainingDefinitionCommand, 

19) 

20from kwai.modules.training.delete_training_definition import ( 

21 DeleteTrainingDefinition, 

22 DeleteTrainingDefinitionCommand, 

23) 

24from kwai.modules.training.get_training_definition import ( 

25 GetTrainingDefinition, 

26 GetTrainingDefinitionCommand, 

27) 

28from kwai.modules.training.get_training_definitions import ( 

29 GetTrainingDefinitions, 

30 GetTrainingDefinitionsCommand, 

31) 

32from kwai.modules.training.get_trainings import GetTrainings, GetTrainingsCommand 

33from kwai.modules.training.teams.team_db_repository import TeamDbRepository 

34from kwai.modules.training.trainings.training_db_repository import TrainingDbRepository 

35from kwai.modules.training.trainings.training_definition_db_repository import ( 

36 TrainingDefinitionDbRepository, 

37) 

38from kwai.modules.training.trainings.training_definition_repository import ( 

39 TrainingDefinitionNotFoundException, 

40) 

41from kwai.modules.training.update_training_definition import ( 

42 UpdateTrainingDefinition, 

43 UpdateTrainingDefinitionCommand, 

44) 

45 

46 

47router = APIRouter() 

48 

49 

50@router.get("/training_definitions") 

51async def get_training_definitions( 

52 pagination: PaginationModel = Depends(PaginationModel), 

53 db=Depends(create_database), 

54) -> TrainingDefinitionDocument: 

55 """Get all training definitions.""" 

56 command = GetTrainingDefinitionsCommand( 

57 offset=pagination.offset or 0, limit=pagination.limit 

58 ) 

59 count, iterator = await GetTrainingDefinitions( 

60 TrainingDefinitionDbRepository(db) 

61 ).execute(command) 

62 

63 document: TrainingDefinitionDocument = TrainingDefinitionDocument( 

64 meta=Meta(count=count, offset=command.offset, limit=command.limit), data=[] 

65 ) 

66 async for training_definition in iterator: 

67 document.merge(TrainingDefinitionDocument.create(training_definition)) 

68 

69 return document 

70 

71 

72@router.get( 

73 "/training_definitions/{training_definition_id}", 

74 responses={ 

75 status.HTTP_404_NOT_FOUND: {"description": "Training definition was not found."} 

76 }, 

77) 

78async def get_training_definition( 

79 training_definition_id: int, 

80 db=Depends(create_database), 

81) -> TrainingDefinitionDocument: 

82 """Get training definition with the given id.""" 

83 command = GetTrainingDefinitionCommand(id=training_definition_id) 

84 try: 

85 training_definition = await GetTrainingDefinition( 

86 TrainingDefinitionDbRepository(db) 

87 ).execute(command) 

88 except TrainingDefinitionNotFoundException as ex: 

89 raise HTTPException( 

90 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) 

91 ) from ex 

92 

93 return TrainingDefinitionDocument.create(training_definition) 

94 

95 

96@router.post( 

97 "/training_definitions", 

98 status_code=status.HTTP_201_CREATED, 

99) 

100async def create_training_definition( 

101 resource: TrainingDefinitionDocument, 

102 db=Depends(create_database), 

103 user: UserEntity = Depends(get_current_user), 

104) -> TrainingDefinitionDocument: 

105 """Create a new training definition.""" 

106 if ( 

107 resource.data.relationships is not None 

108 and resource.data.relationships.team is not None 

109 and resource.data.relationships.team.data is not None 

110 ): 

111 team_id = int(resource.data.relationships.team.data.id) 

112 else: 

113 team_id = None 

114 

115 command = CreateTrainingDefinitionCommand( 

116 name=resource.data.attributes.name, 

117 description=resource.data.attributes.description, 

118 weekday=resource.data.attributes.weekday, 

119 start_time=resource.data.attributes.start_time, 

120 end_time=resource.data.attributes.end_time, 

121 timezone=resource.data.attributes.timezone, 

122 active=resource.data.attributes.active, 

123 location=resource.data.attributes.location or "", 

124 remark=resource.data.attributes.remark or "", 

125 team_id=team_id, 

126 ) 

127 try: 

128 training_definition = await CreateTrainingDefinition( 

129 TrainingDefinitionDbRepository(db), 

130 TeamDbRepository(db), 

131 Owner(id=user.id, uuid=user.uuid, name=user.name), 

132 ).execute(command) 

133 except ValueError as ve: 

134 raise HTTPException( 

135 status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(ve) 

136 ) from ve 

137 

138 return TrainingDefinitionDocument.create(training_definition) 

139 

140 

141@router.patch( 

142 "/training_definitions/{training_definition_id}", 

143 responses={ 

144 status.HTTP_404_NOT_FOUND: {"description": "Training definition was not found."} 

145 }, 

146) 

147async def update_training_definition( 

148 training_definition_id: int, 

149 resource: TrainingDefinitionDocument, 

150 db=Depends(create_database), 

151 user: UserEntity = Depends(get_current_user), 

152) -> TrainingDefinitionDocument: 

153 """Update a training definition.""" 

154 if ( 

155 resource.data.relationships is not None 

156 and resource.data.relationships.team is not None 

157 and resource.data.relationships.team.data is not None 

158 ): 

159 team_id = int(resource.data.relationships.team.data.id) 

160 else: 

161 team_id = None 

162 command = UpdateTrainingDefinitionCommand( 

163 id=training_definition_id, 

164 name=resource.data.attributes.name, 

165 description=resource.data.attributes.description, 

166 weekday=resource.data.attributes.weekday, 

167 start_time=resource.data.attributes.start_time, 

168 end_time=resource.data.attributes.end_time, 

169 timezone=resource.data.attributes.timezone, 

170 active=resource.data.attributes.active, 

171 location=resource.data.attributes.location or "", 

172 remark=resource.data.attributes.remark or "", 

173 team_id=team_id, 

174 ) 

175 try: 

176 training_definition = await UpdateTrainingDefinition( 

177 TrainingDefinitionDbRepository(db), 

178 TeamDbRepository(db), 

179 Owner(id=user.id, uuid=user.uuid, name=user.name), 

180 ).execute(command) 

181 except TrainingDefinitionNotFoundException as ex: 

182 raise HTTPException( 

183 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) 

184 ) from ex 

185 except ValueError as ve: 

186 raise HTTPException( 

187 status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(ve) 

188 ) from ve 

189 

190 return TrainingDefinitionDocument.create(training_definition) 

191 

192 

193@router.delete( 

194 "/training_definitions/{training_definition_id}", 

195 responses={ 

196 status.HTTP_404_NOT_FOUND: {"description": "Training definition was not found."} 

197 }, 

198) 

199async def delete_training_definition( 

200 training_definition_id: int, 

201 db=Depends(create_database), 

202 user: UserEntity = Depends(get_current_user), 

203) -> None: 

204 """Delete a training definition.""" 

205 command = DeleteTrainingDefinitionCommand( 

206 id=training_definition_id, delete_trainings=False 

207 ) 

208 await DeleteTrainingDefinition( 

209 TrainingDefinitionDbRepository(db), TrainingDbRepository(db) 

210 ).execute(command) 

211 

212 

213@router.get( 

214 "/training_definitions/{training_definition_id}/trainings", 

215 responses={ 

216 status.HTTP_404_NOT_FOUND: { 

217 "description": "Training definition or coach was not found." 

218 } 

219 }, 

220) 

221async def get_trainings( 

222 training_definition_id: int, 

223 pagination: PaginationModel = Depends(PaginationModel), 

224 trainings_filter: TrainingsFilterModel = Depends(TrainingsFilterModel), 

225 db=Depends(create_database), 

226) -> TrainingDocument: 

227 """Get trainings of the given training definition.""" 

228 command = GetTrainingsCommand( 

229 offset=pagination.offset or 0, 

230 limit=pagination.limit, 

231 year=trainings_filter.year, 

232 month=trainings_filter.month, 

233 start=trainings_filter.start, 

234 end=trainings_filter.end, 

235 active=trainings_filter.active, 

236 coach=trainings_filter.coach, 

237 definition=training_definition_id, 

238 ) 

239 

240 try: 

241 count, training_iterator = await GetTrainings( 

242 TrainingDbRepository(db), 

243 CoachDbRepository(db), 

244 TrainingDefinitionDbRepository(db), 

245 ).execute(command) 

246 except TrainingDefinitionNotFoundException as ex: 

247 raise HTTPException( 

248 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) 

249 ) from ex 

250 except CoachNotFoundException as ex: 

251 raise HTTPException( 

252 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) 

253 ) from ex 

254 

255 document: TrainingDocument = TrainingDocument( 

256 meta=Meta(count=count, offset=command.offset, limit=command.limit), data=[] 

257 ) 

258 async for training in training_iterator: 

259 document.merge(TrainingDocument.create(training)) 

260 

261 return document