Coverage for mindsdb / integrations / handlers / ms_teams_handler / ms_teams_tables.py: 80%

114 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-21 00:36 +0000

1from typing import List 

2 

3import pandas as pd 

4 

5from mindsdb.integrations.handlers.ms_teams_handler.ms_graph_api_teams_client import MSGraphAPITeamsDelegatedPermissionsClient 

6from mindsdb.integrations.libs.api_handler import APIResource 

7from mindsdb.integrations.utilities.sql_utils import ( 

8 FilterCondition, 

9 FilterOperator, 

10 SortColumn 

11) 

12 

13 

14class TeamsTable(APIResource): 

15 """ 

16 The table abstraction for the 'teams' resource of the Microsoft Graph API. 

17 """ 

18 

19 def list( 

20 self, 

21 conditions: List[FilterCondition] = None, 

22 limit: int = None, 

23 sort: List[SortColumn] = None, 

24 targets: List[str] = None, 

25 **kwargs 

26 ): 

27 """ 

28 Executes a parsed SELECT SQL query on the 'teams' resource of the Microsoft Graph API. 

29 

30 Args: 

31 conditions (List[FilterCondition]): The list of parsed filter conditions. 

32 limit (int): The maximum number of records to return. 

33 sort (List[SortColumn]): The list of parsed sort columns. 

34 targets (List[str]): The list of target columns to return. 

35 """ 

36 client: MSGraphAPITeamsDelegatedPermissionsClient = self.handler.connect() 

37 teams = client.get_teams() 

38 

39 teams_df = pd.json_normalize(teams, sep="_") 

40 teams_df = teams_df.reindex(columns=self.get_columns(), fill_value=None) 

41 

42 return teams_df 

43 

44 def get_columns(self) -> List[str]: 

45 """ 

46 Retrieves the attributes (columns) of the 'teams' resource. 

47 

48 Returns: 

49 List[Text]: A list of attributes (columns) of the 'teams' resource. 

50 """ 

51 return [ 

52 "id", 

53 "createdDateTime", 

54 "displayName", 

55 "description", 

56 "internalId", 

57 "classification", 

58 "specialization", 

59 "visibility", 

60 "webUrl", 

61 "isArchived", 

62 "tenantId", 

63 "isMembershipLimitedToOwners", 

64 ] 

65 

66 

67class ChannelsTable(APIResource): 

68 """ 

69 The table abstraction for the 'channels' resource of the Microsoft Graph API. 

70 """ 

71 

72 def list( 

73 self, 

74 conditions: List[FilterCondition] = None, 

75 limit: int = None, 

76 sort: List[SortColumn] = None, 

77 targets: List[str] = None, 

78 **kwargs 

79 ): 

80 """ 

81 Executes a parsed SELECT SQL query on the 'channels' resource of the Microsoft Graph API. 

82 

83 Args: 

84 conditions (List[FilterCondition]): The list of parsed filter conditions. 

85 limit (int): The maximum number of records to return. 

86 sort (List[SortColumn]): The list of parsed sort columns. 

87 targets (List[str]): The list of target columns to return. 

88 """ 

89 client: MSGraphAPITeamsDelegatedPermissionsClient = self.handler.connect() 

90 channels = [] 

91 

92 team_id, channel_ids = None, None 

93 for condition in conditions: 

94 if condition.column == "teamId": 

95 if condition.op == FilterOperator.EQUAL: 95 ↛ 99line 95 didn't jump to line 99 because the condition on line 95 was always true

96 team_id = condition.value 

97 

98 else: 

99 raise ValueError( 

100 f"Unsupported operator '{condition.op}' for column 'teamId'." 

101 ) 

102 

103 condition.applied = True 

104 

105 if condition.column == "id": 

106 if condition.op == FilterOperator.EQUAL: 106 ↛ 109line 106 didn't jump to line 109 because the condition on line 106 was always true

107 channel_ids = [condition.value] 

108 

109 elif condition.op == FilterOperator.IN: 

110 channel_ids = condition.value 

111 

112 else: 

113 raise ValueError( 

114 f"Unsupported operator '{condition.op}' for column 'id'." 

115 ) 

116 

117 condition.applied = True 

118 

119 channels = client.get_channels(team_id, channel_ids) 

120 

121 channels_df = pd.json_normalize(channels, sep="_") 

122 channels_df = channels_df[self.get_columns()] 

123 

124 return channels_df 

125 

126 def get_columns(self) -> List[str]: 

127 """ 

128 Retrieves the attributes (columns) of the 'chats' resource. 

129 

130 Returns: 

131 List[Text]: A list of attributes (columns) of the 'chats' resource. 

132 """ 

133 return [ 

134 "id", 

135 "createdDateTime", 

136 "displayName", 

137 "description", 

138 "isFavoriteByDefault", 

139 "email", 

140 "tenantId", 

141 "webUrl", 

142 "membershipType", 

143 "teamId", 

144 ] 

145 

146 

147class ChannelMessagesTable(APIResource): 

148 """ 

149 The table abstraction for the 'channel messages' resource of the Microsoft Graph API. 

150 """ 

151 

152 def list( 

153 self, 

154 conditions: List[FilterCondition] = None, 

155 limit: int = None, 

156 sort: List[SortColumn] = None, 

157 targets: List[str] = None, 

158 **kwargs 

159 ): 

160 """ 

161 Executes a parsed SELECT SQL query on the 'channel messages' resource of the Microsoft Graph API. 

162 

163 Args: 

164 conditions (List[FilterCondition]): The list of parsed filter conditions. 

165 limit (int): The maximum number of records to return. 

166 sort (List[SortColumn]): The list of parsed sort columns. 

167 targets (List[str]): The list of target columns to return. 

168 """ 

169 client: MSGraphAPITeamsDelegatedPermissionsClient = self.handler.connect() 

170 messages = [] 

171 

172 group_id, channel_id, message_ids = None, None, None 

173 for condition in conditions: 

174 if condition.column == "channelIdentity_teamId": 

175 if condition.op == FilterOperator.EQUAL: 175 ↛ 179line 175 didn't jump to line 179 because the condition on line 175 was always true

176 group_id = condition.value 

177 

178 else: 

179 raise ValueError( 

180 f"Unsupported operator '{condition.op}' for column 'channelIdentity_teamId'." 

181 ) 

182 

183 condition.applied = True 

184 

185 if condition.column == "channelIdentity_channelId": 

186 if condition.op == FilterOperator.EQUAL: 186 ↛ 190line 186 didn't jump to line 190 because the condition on line 186 was always true

187 channel_id = condition.value 

188 

189 else: 

190 raise ValueError( 

191 f"Unsupported operator '{condition.op}' for column 'channelIdentity_channelId'." 

192 ) 

193 

194 condition.applied = True 

195 

196 if condition.column == "id": 

197 if condition.op == FilterOperator.EQUAL: 197 ↛ 200line 197 didn't jump to line 200 because the condition on line 197 was always true

198 message_ids = [condition.value] 

199 

200 elif condition.op == FilterOperator.IN: 

201 message_ids = condition.value 

202 

203 else: 

204 raise ValueError( 

205 f"Unsupported operator '{condition.op}' for column 'id'." 

206 ) 

207 

208 condition.applied = True 

209 

210 if not group_id or not channel_id: 

211 raise ValueError("The 'channelIdentity_teamId' and 'channelIdentity_channelId' columns are required.") 

212 

213 messages = client.get_channel_messages(group_id, channel_id, message_ids) 

214 

215 messages_df = pd.json_normalize(messages, sep="_") 

216 messages_df = messages_df[self.get_columns()] 

217 

218 return messages_df 

219 

220 def get_columns(self) -> List[str]: 

221 """ 

222 Retrieves the attributes (columns) of the 'chat messages' resource. 

223 

224 Returns: 

225 List[Text]: A list of attributes (columns) of the 'chat messages' resource. 

226 """ 

227 return [ 

228 "id", 

229 "replyToId", 

230 "etag", 

231 "messageType", 

232 "createdDateTime", 

233 "lastModifiedDateTime", 

234 "lastEditedDateTime", 

235 "deletedDateTime", 

236 "subject", 

237 "summary", 

238 "chatId", 

239 "importance", 

240 "locale", 

241 "webUrl", 

242 "policyViolation", 

243 "from_application", 

244 "from_device", 

245 "from_user_id", 

246 "from_user_displayName", 

247 "from_user_userIdentityType", 

248 "body_contentType", 

249 "body_content", 

250 "channelIdentity_teamId", 

251 "channelIdentity_channelId", 

252 ] 

253 

254 

255class ChatsTable(APIResource): 

256 """ 

257 The table abstraction for the 'chats' resource of the Microsoft Graph API. 

258 """ 

259 

260 def list( 

261 self, 

262 conditions: List[FilterCondition] = None, 

263 limit: int = None, 

264 sort: List[SortColumn] = None, 

265 targets: List[str] = None, 

266 **kwargs 

267 ): 

268 """ 

269 Executes a parsed SELECT SQL query on the 'chats' resource of the Microsoft Graph API. 

270 

271 Args: 

272 conditions (List[FilterCondition]): The list of parsed filter conditions. 

273 limit (int): The maximum number of records to return. 

274 sort (List[SortColumn]): The list of parsed sort columns. 

275 targets (List[str]): The list of target columns to return. 

276 """ 

277 client: MSGraphAPITeamsDelegatedPermissionsClient = self.handler.connect() 

278 chats = [] 

279 

280 chat_ids = None 

281 for condition in conditions: 

282 if condition.column == "id": 282 ↛ 281line 282 didn't jump to line 281 because the condition on line 282 was always true

283 if condition.op == FilterOperator.EQUAL: 283 ↛ 286line 283 didn't jump to line 286 because the condition on line 283 was always true

284 chat_ids = [condition.value] 

285 

286 elif condition.op == FilterOperator.IN: 

287 chat_ids = condition.value 

288 

289 else: 

290 raise ValueError( 

291 f"Unsupported operator '{condition.op}' for column 'id'." 

292 ) 

293 

294 condition.applied = True 

295 

296 chats = client.get_chats(chat_ids) 

297 

298 chats_df = pd.json_normalize(chats, sep="_") 

299 chats_df = chats_df[self.get_columns()] 

300 

301 return chats_df 

302 

303 def get_columns(self) -> List[str]: 

304 """ 

305 Retrieves the attributes (columns) of the 'chats' resource. 

306 

307 Returns: 

308 List[Text]: A list of attributes (columns) of the 'chats' resource. 

309 """ 

310 return [ 

311 "id", 

312 "topic", 

313 "createdDateTime", 

314 "lastUpdatedDateTime", 

315 "chatType", 

316 "webUrl", 

317 "isHiddenForAllMembers" 

318 ] 

319 

320 

321class ChatMessagesTable(APIResource): 

322 """ 

323 The table abstraction for the 'chat messages' resource of the Microsoft Graph API. 

324 """ 

325 

326 def list( 

327 self, 

328 conditions: List[FilterCondition] = None, 

329 limit: int = None, 

330 sort: List[SortColumn] = None, 

331 targets: List[str] = None, 

332 **kwargs 

333 ): 

334 """ 

335 Executes a parsed SELECT SQL query on the 'chat messages' resource of the Microsoft Graph API. 

336 

337 Args: 

338 conditions (List[FilterCondition]): The list of parsed filter conditions. 

339 limit (int): The maximum number of records to return. 

340 sort (List[SortColumn]): The list of parsed sort columns. 

341 targets (List[str]): The list of target columns to return. 

342 """ 

343 client: MSGraphAPITeamsDelegatedPermissionsClient = self.handler.connect() 

344 messages = [] 

345 

346 chat_id, message_ids = None, None 

347 for condition in conditions: 

348 if condition.column == "chatId": 

349 if condition.op == FilterOperator.EQUAL: 349 ↛ 353line 349 didn't jump to line 353 because the condition on line 349 was always true

350 chat_id = condition.value 

351 

352 else: 

353 raise ValueError( 

354 f"Unsupported operator '{condition.op}' for column 'chatId'." 

355 ) 

356 

357 condition.applied = True 

358 

359 if condition.column == "id": 

360 if condition.op == FilterOperator.EQUAL: 360 ↛ 363line 360 didn't jump to line 363 because the condition on line 360 was always true

361 message_ids = [condition.value] 

362 

363 elif condition.op == FilterOperator.IN: 

364 message_ids = condition.value 

365 

366 else: 

367 raise ValueError( 

368 f"Unsupported operator '{condition.op}' for column 'id'." 

369 ) 

370 

371 condition.applied = True 

372 

373 if not chat_id: 

374 raise ValueError("The 'chatId' column is required.") 

375 

376 messages = client.get_chat_messages(chat_id, message_ids) 

377 

378 messages_df = pd.json_normalize(messages, sep="_") 

379 messages_df = messages_df[self.get_columns()] 

380 

381 return messages_df 

382 

383 def get_columns(self) -> List[str]: 

384 """ 

385 Retrieves the attributes (columns) of the 'chat messages' resource. 

386 

387 Returns: 

388 List[Text]: A list of attributes (columns) of the 'chat messages' resource. 

389 """ 

390 return [ 

391 "id", 

392 "replyToId", 

393 "etag", 

394 "messageType", 

395 "createdDateTime", 

396 "lastModifiedDateTime", 

397 "lastEditedDateTime", 

398 "deletedDateTime", 

399 "subject", 

400 "summary", 

401 "chatId", 

402 "importance", 

403 "locale", 

404 "webUrl", 

405 "policyViolation", 

406 "from_application", 

407 "from_device", 

408 "from_user_id", 

409 "from_user_displayName", 

410 "from_user_userIdentityType", 

411 "body_contentType", 

412 "body_content", 

413 ]