Coverage for apps/kwai-api/src/kwai_api/v1/trainings/presenters.py: 100%

40 statements  

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

1"""Module for defining presenters for the /api/v1/trainings endpoints.""" 

2 

3from typing import Self, TypeAlias 

4 

5from kwai_bc_training.trainings.training import TrainingEntity 

6from kwai_core.domain.presenter import AsyncPresenter, IterableResult, Presenter 

7from kwai_core.json_api import ( 

8 JsonApiPresenter, 

9 Meta, 

10 Relationship, 

11 RelationshipList, 

12 ResourceMeta, 

13) 

14 

15from kwai_api.converter import MarkdownConverter 

16from kwai_api.schemas.resources import ( 

17 TeamResourceIdentifier, 

18 TrainingScheduleResourceIdentifier, 

19) 

20from kwai_api.v1.trainings.coaches.presenters import JsonApiTrainingCoachesPresenter 

21from kwai_api.v1.trainings.coaches.schemas import ( 

22 TrainingCoachResourceIdentifier, 

23) 

24from kwai_api.v1.trainings.schemas import ( 

25 TrainingAttributes, 

26 TrainingDocument, 

27 TrainingEvent, 

28 TrainingRelationships, 

29 TrainingResource, 

30 TrainingScheduleAttributes, 

31 TrainingScheduleDocument, 

32 TrainingScheduleResource, 

33 TrainingsDocument, 

34 TrainingText, 

35) 

36from kwai_api.v1.trainings.teams.schemas import ( 

37 TeamAttributes, 

38 TeamDocument, 

39 TeamResource, 

40) 

41 

42 

43TrainingSchemaRelationship: TypeAlias = Relationship[TrainingScheduleResourceIdentifier] 

44 

45 

46class JsonApiTrainingPresenter( 

47 JsonApiPresenter[TrainingDocument], Presenter[TrainingEntity] 

48): 

49 """A presenter that transforms a training entity into a JSON:API document.""" 

50 

51 def __init__(self): 

52 super().__init__() 

53 

54 def present(self, training: TrainingEntity) -> Self: 

55 self._document = TrainingDocument( 

56 data=TrainingResource( 

57 id=str(training.id), 

58 meta=ResourceMeta( 

59 created_at=str(training.traceable_time.created_at), 

60 updated_at=str(training.traceable_time.updated_at), 

61 ), 

62 attributes=TrainingAttributes( 

63 texts=[ 

64 TrainingText( 

65 locale=text.locale.value, 

66 format=text.format.value, 

67 title=text.title, 

68 summary=MarkdownConverter().convert(text.summary), 

69 content=MarkdownConverter().convert(text.content) 

70 if text.content 

71 else None, 

72 original_summary=text.summary, 

73 original_content=text.content, 

74 ) 

75 for text in training.texts 

76 ], 

77 event=TrainingEvent( 

78 start_date=str(training.period.start_date), 

79 end_date=str(training.period.end_date), 

80 location=training.location or "", 

81 cancelled=training.cancelled, 

82 active=training.active, 

83 ), 

84 remark=training.remark or "", 

85 ), 

86 relationships=TrainingRelationships( 

87 coaches=RelationshipList[TrainingCoachResourceIdentifier](), 

88 teams=RelationshipList[TeamResourceIdentifier](), 

89 schedule=TrainingSchemaRelationship(), 

90 ), 

91 ) 

92 ) 

93 

94 training_coach_documents = ( 

95 JsonApiTrainingCoachesPresenter().present(training).get_document() 

96 ) 

97 for training_coach_resource in training_coach_documents.data: 

98 self._document.data.relationships.coaches.data.append( 

99 TrainingCoachResourceIdentifier(id=training_coach_resource.id) 

100 ) 

101 self._document.included |= {training_coach_resource} 

102 

103 if training.schedule: 

104 training_schedule_document = TrainingScheduleDocument( 

105 data=TrainingScheduleResource( 

106 id=str(training.schedule.id), 

107 attributes=TrainingScheduleAttributes(name=training.schedule.name), 

108 ) 

109 ) 

110 self._document.data.relationships.schedule.data = ( 

111 TrainingScheduleResourceIdentifier(id=str(training.schedule.id)) 

112 ) 

113 self._document.included.add(training_schedule_document.data) 

114 self._document.included |= training_schedule_document.included 

115 

116 for team in training.teams: 

117 self._document.data.relationships.teams.data.append( 

118 TeamResourceIdentifier(id=str(team.id)) 

119 ) 

120 team_document = TeamDocument( 

121 data=TeamResource( 

122 id=str(team.id), attributes=TeamAttributes(name=team.name) 

123 ) 

124 ) 

125 self._document.included.add(team_document.data) 

126 

127 return self 

128 

129 

130class JsonApiTrainingsDocumentPresenter( 

131 JsonApiPresenter[TrainingsDocument], AsyncPresenter[IterableResult[TrainingEntity]] 

132): 

133 """A presenter for transforming an iterator with trainings into a JSON:API document.""" 

134 

135 async def present(self, result: IterableResult[TrainingEntity]) -> Self: 

136 self._document = TrainingsDocument( 

137 meta=Meta(count=result.count, offset=result.offset, limit=result.limit) 

138 ) 

139 async for training in result.iterator: 

140 training_presenter = JsonApiTrainingPresenter() 

141 training_presenter.present(training) 

142 training_document = training_presenter.get_document() 

143 self._document.data.append(training_document.data) 

144 self._document.included |= training_document.included 

145 

146 return self