MindsDB 25.3.4.1__py3-none-any.whl → 25.4.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of MindsDB might be problematic. Click here for more details.
- mindsdb/__about__.py +1 -1
- mindsdb/__main__.py +21 -4
- mindsdb/api/executor/datahub/datanodes/integration_datanode.py +5 -2
- mindsdb/api/executor/datahub/datanodes/system_tables.py +131 -138
- mindsdb/api/mcp/__init__.py +0 -0
- mindsdb/api/mcp/start.py +152 -0
- mindsdb/api/mysql/mysql_proxy/libs/constants/mysql.py +74 -0
- mindsdb/integrations/handlers/confluence_handler/confluence_api_client.py +14 -2
- mindsdb/integrations/handlers/ms_teams_handler/ms_graph_api_teams_client.py +278 -55
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_handler.py +52 -21
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_tables.py +6 -29
- mindsdb/integrations/handlers/mssql_handler/mssql_handler.py +37 -1
- mindsdb/integrations/handlers/mysql_handler/mysql_handler.py +28 -1
- mindsdb/integrations/handlers/oracle_handler/oracle_handler.py +53 -5
- mindsdb/integrations/handlers/postgres_handler/postgres_handler.py +37 -1
- mindsdb/integrations/handlers/snowflake_handler/snowflake_handler.py +42 -1
- mindsdb/integrations/libs/vectordatabase_handler.py +20 -20
- mindsdb/integrations/utilities/handlers/auth_utilities/__init__.py +1 -1
- mindsdb/integrations/utilities/handlers/auth_utilities/microsoft/__init__.py +1 -1
- mindsdb/integrations/utilities/handlers/auth_utilities/microsoft/ms_graph_api_auth_utilities.py +97 -18
- mindsdb/integrations/utilities/rag/rerankers/reranker_compressor.py +121 -11
- mindsdb/interfaces/database/projects.py +15 -0
- mindsdb/interfaces/knowledge_base/controller.py +78 -2
- mindsdb/utilities/config.py +8 -0
- mindsdb/utilities/render/sqlalchemy_render.py +30 -6
- mindsdb/utilities/starters.py +7 -0
- {mindsdb-25.3.4.1.dist-info → mindsdb-25.4.1.0.dist-info}/METADATA +233 -234
- {mindsdb-25.3.4.1.dist-info → mindsdb-25.4.1.0.dist-info}/RECORD +31 -29
- {mindsdb-25.3.4.1.dist-info → mindsdb-25.4.1.0.dist-info}/WHEEL +0 -0
- {mindsdb-25.3.4.1.dist-info → mindsdb-25.4.1.0.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.3.4.1.dist-info → mindsdb-25.4.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
from
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Text, List, Dict
|
|
2
3
|
|
|
3
4
|
from requests.exceptions import RequestException
|
|
4
5
|
|
|
5
6
|
from mindsdb.integrations.utilities.handlers.api_utilities.microsoft.ms_graph_api_utilities import MSGraphAPIBaseClient
|
|
6
7
|
from mindsdb.utilities import log
|
|
7
8
|
|
|
9
|
+
|
|
8
10
|
logger = log.getLogger(__name__)
|
|
9
11
|
|
|
10
12
|
|
|
11
|
-
class
|
|
13
|
+
class MSGraphAPITeamsClient(MSGraphAPIBaseClient, ABC):
|
|
12
14
|
"""
|
|
13
|
-
The Microsoft Graph API client for the Microsoft Teams handler
|
|
14
|
-
This client is used for accessing the Microsoft Teams specific endpoints of the Microsoft Graph API.
|
|
15
|
-
Several common methods for submitting requests, fetching data, etc. are inherited from the base class.
|
|
15
|
+
The base class for the Microsoft Graph API client for the Microsoft Teams handler.
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
def check_connection(self) -> bool:
|
|
@@ -23,21 +23,89 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
23
23
|
bool: True if the connection is established, False otherwise.
|
|
24
24
|
"""
|
|
25
25
|
try:
|
|
26
|
-
self.
|
|
26
|
+
self._get_all_groups()
|
|
27
27
|
return True
|
|
28
28
|
except RequestException as request_error:
|
|
29
29
|
logger.error(f"Failed to check connection to Microsoft Teams: {request_error}")
|
|
30
30
|
return False
|
|
31
31
|
|
|
32
|
-
def
|
|
32
|
+
def get_teams(self) -> List[Dict]:
|
|
33
33
|
"""
|
|
34
|
-
Get
|
|
34
|
+
Get teams from Microsoft Teams.
|
|
35
35
|
|
|
36
36
|
Returns:
|
|
37
|
-
List[Dict]: The
|
|
37
|
+
List[Dict]: The teams data.
|
|
38
38
|
"""
|
|
39
|
-
return self.
|
|
39
|
+
return self._get_all_groups()
|
|
40
40
|
|
|
41
|
+
def get_channels(self, group_id: Text = None, channel_ids: List[Text] = None) -> List[Dict]:
|
|
42
|
+
"""
|
|
43
|
+
Get channels from Microsoft Teams.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
group_id (Text): The ID of the group that the channels belong to.
|
|
47
|
+
channel_ids (List[Text]): The IDs of the channels.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
List[Dict]: The channels data.
|
|
51
|
+
"""
|
|
52
|
+
if group_id and channel_ids:
|
|
53
|
+
return self._get_channels_in_group_by_ids(group_id, channel_ids)
|
|
54
|
+
elif group_id:
|
|
55
|
+
return self._get_all_channels_in_group(group_id)
|
|
56
|
+
elif channel_ids:
|
|
57
|
+
return self._get_channels_across_all_groups_by_ids(channel_ids)
|
|
58
|
+
else:
|
|
59
|
+
return self._get_all_channels_across_all_groups()
|
|
60
|
+
|
|
61
|
+
def get_channel_messages(self, group_id: Text, channel_id: Text, message_ids: List[Text] = None) -> List[Dict]:
|
|
62
|
+
"""
|
|
63
|
+
Get channel messages from Microsoft Teams.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
group_id (Text): The ID of the group that the channel belongs to.
|
|
67
|
+
channel_id (Text): The ID of the channel that the messages belong to.
|
|
68
|
+
message_ids (List[Text]): The IDs of the messages.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
List[Dict]: The messages data.
|
|
72
|
+
"""
|
|
73
|
+
if message_ids:
|
|
74
|
+
return self._get_messages_in_channel_by_ids(group_id, channel_id, message_ids)
|
|
75
|
+
else:
|
|
76
|
+
return self._get_all_messages_in_channel(group_id, channel_id)
|
|
77
|
+
|
|
78
|
+
def get_chats(self, chat_ids: List[Text] = None) -> List[Dict]:
|
|
79
|
+
"""
|
|
80
|
+
Get chats from Microsoft Teams.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
chat_ids (List[Text]): The IDs of the chats.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
List[Dict]: The chats data.
|
|
87
|
+
"""
|
|
88
|
+
if chat_ids:
|
|
89
|
+
return self._get_chats_by_ids(chat_ids)
|
|
90
|
+
else:
|
|
91
|
+
return self._get_all_chats()
|
|
92
|
+
|
|
93
|
+
def get_chat_messages(self, chat_id: Text, message_ids: List[Text] = None) -> List[Dict]:
|
|
94
|
+
"""
|
|
95
|
+
Get chat messages from Microsoft Teams.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
chat_id (Text): The ID of the chat that the messages belong to.
|
|
99
|
+
message_ids (List[Text]): The IDs of the messages.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
List[Dict]: The messages data.
|
|
103
|
+
"""
|
|
104
|
+
if message_ids:
|
|
105
|
+
return self._get_messages_in_chat_by_ids(chat_id, message_ids)
|
|
106
|
+
else:
|
|
107
|
+
return self._get_all_messages_in_chat(chat_id)
|
|
108
|
+
|
|
41
109
|
def _get_all_group_ids(self) -> List[Text]:
|
|
42
110
|
"""
|
|
43
111
|
Get all group IDs related to Microsoft Teams.
|
|
@@ -46,12 +114,75 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
46
114
|
List[Text]: The group IDs.
|
|
47
115
|
"""
|
|
48
116
|
if not self._group_ids:
|
|
49
|
-
groups = self.
|
|
117
|
+
groups = self._get_all_groups()
|
|
50
118
|
self._group_ids = [group["id"] for group in groups]
|
|
51
119
|
|
|
52
120
|
return self._group_ids
|
|
53
121
|
|
|
54
|
-
|
|
122
|
+
@abstractmethod
|
|
123
|
+
def _get_all_groups(self) -> List[Dict]:
|
|
124
|
+
"""
|
|
125
|
+
Get all groups related to Microsoft Teams.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
List[Dict]: The groups data.
|
|
129
|
+
"""
|
|
130
|
+
pass
|
|
131
|
+
|
|
132
|
+
@abstractmethod
|
|
133
|
+
def _get_chat_by_id(self, chat_id: Text) -> Dict:
|
|
134
|
+
"""
|
|
135
|
+
Get a chat by its ID.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
chat_id (Text): The ID of the chat.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
Dict: The chat data.
|
|
142
|
+
"""
|
|
143
|
+
pass
|
|
144
|
+
|
|
145
|
+
@abstractmethod
|
|
146
|
+
def _get_all_chats(self, limit: int = None) -> List[Dict]:
|
|
147
|
+
"""
|
|
148
|
+
Get all chats related to Microsoft Teams.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
limit (int): The maximum number of chats to return.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
List[Dict]: The chats data.
|
|
155
|
+
"""
|
|
156
|
+
pass
|
|
157
|
+
|
|
158
|
+
@abstractmethod
|
|
159
|
+
def _get_message_in_chat_by_id(self, chat_id: Text, message_id: Text) -> Dict:
|
|
160
|
+
"""
|
|
161
|
+
Get a message by its ID and the ID of the chat that it belongs to.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
chat_id (Text): The ID of the chat that the message belongs to.
|
|
165
|
+
message_id (Text): The ID of the message.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
Dict: The message data.
|
|
169
|
+
"""
|
|
170
|
+
pass
|
|
171
|
+
|
|
172
|
+
@abstractmethod
|
|
173
|
+
def _get_all_messages_in_chat(self, chat_id: Text, limit: int = None) -> List[Dict]:
|
|
174
|
+
"""
|
|
175
|
+
Get messages of a chat by its ID.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
chat_id (Text): The ID of the chat.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
List[Dict]: The messages data.
|
|
182
|
+
"""
|
|
183
|
+
pass
|
|
184
|
+
|
|
185
|
+
def _get_channel_in_group_by_id(self, group_id: Text, channel_id: Text) -> Dict:
|
|
55
186
|
"""
|
|
56
187
|
Get a channel by its ID and the ID of the group that it belongs to.
|
|
57
188
|
|
|
@@ -68,7 +199,7 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
68
199
|
|
|
69
200
|
return channel
|
|
70
201
|
|
|
71
|
-
def
|
|
202
|
+
def _get_channels_in_group_by_ids(self, group_id: Text, channel_ids: List[Text]) -> List[Dict]:
|
|
72
203
|
"""
|
|
73
204
|
Get channels by their IDs and the ID of the group that they belong to.
|
|
74
205
|
|
|
@@ -81,11 +212,11 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
81
212
|
"""
|
|
82
213
|
channels = []
|
|
83
214
|
for channel_id in channel_ids:
|
|
84
|
-
channels.append(self.
|
|
215
|
+
channels.append(self._get_channel_in_group_by_id(group_id, channel_id))
|
|
85
216
|
|
|
86
217
|
return channels
|
|
87
|
-
|
|
88
|
-
def
|
|
218
|
+
|
|
219
|
+
def _get_all_channels_in_group(self, group_id: Text) -> List[Dict]:
|
|
89
220
|
"""
|
|
90
221
|
Get all channels of a group by its ID.
|
|
91
222
|
|
|
@@ -101,20 +232,20 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
101
232
|
|
|
102
233
|
return channels
|
|
103
234
|
|
|
104
|
-
def
|
|
235
|
+
def _get_all_channels_across_all_groups(self) -> List[Dict]:
|
|
105
236
|
"""
|
|
106
|
-
Get all channels across all groups
|
|
237
|
+
Get all channels across all groups related to Microsoft Teams.
|
|
107
238
|
|
|
108
239
|
Returns:
|
|
109
240
|
List[Dict]: The channels data.
|
|
110
241
|
"""
|
|
111
242
|
channels = []
|
|
112
243
|
for group_id in self._get_all_group_ids():
|
|
113
|
-
channels += self.
|
|
244
|
+
channels += self._get_all_channels_in_group(group_id)
|
|
114
245
|
|
|
115
246
|
return channels
|
|
116
247
|
|
|
117
|
-
def
|
|
248
|
+
def _get_channels_across_all_groups_by_ids(self, channel_ids: List[Text]) -> List[Dict]:
|
|
118
249
|
"""
|
|
119
250
|
Get channels by their IDs.
|
|
120
251
|
|
|
@@ -124,11 +255,11 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
124
255
|
Returns:
|
|
125
256
|
List[Dict]: The channels data.
|
|
126
257
|
"""
|
|
127
|
-
channels = self.
|
|
258
|
+
channels = self._get_all_channels_across_all_groups()
|
|
128
259
|
|
|
129
260
|
return [channel for channel in channels if channel["id"] in channel_ids]
|
|
130
261
|
|
|
131
|
-
def
|
|
262
|
+
def _get_message_in_channel_by_id(self, group_id: Text, channel_id: Text, message_id: Text) -> Dict:
|
|
132
263
|
"""
|
|
133
264
|
Get a message by its ID, the ID of the group that it belongs to, and the ID of the channel that it belongs to.
|
|
134
265
|
|
|
@@ -142,7 +273,7 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
142
273
|
"""
|
|
143
274
|
return self.fetch_data_json(f"teams/{group_id}/channels/{channel_id}/messages/{message_id}")
|
|
144
275
|
|
|
145
|
-
def
|
|
276
|
+
def _get_messages_in_channel_by_ids(self, group_id: Text, channel_id: Text, message_ids: List[Text]) -> List[Dict]:
|
|
146
277
|
"""
|
|
147
278
|
Get messages by their IDs, the ID of the group that they belong to, and the ID of the channel that they belong to.
|
|
148
279
|
|
|
@@ -156,11 +287,11 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
156
287
|
"""
|
|
157
288
|
messages = []
|
|
158
289
|
for message_id in message_ids:
|
|
159
|
-
messages.append(self.
|
|
290
|
+
messages.append(self._get_message_in_channel_by_id(group_id, channel_id, message_id))
|
|
160
291
|
|
|
161
292
|
return messages
|
|
162
293
|
|
|
163
|
-
def
|
|
294
|
+
def _get_all_messages_in_channel(self, group_id: Text, channel_id: Text, limit: int = None) -> List[Dict]:
|
|
164
295
|
"""
|
|
165
296
|
Get messages of a channel by its ID and the ID of the group that it belongs to.
|
|
166
297
|
|
|
@@ -180,7 +311,60 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
180
311
|
|
|
181
312
|
return messages[:limit]
|
|
182
313
|
|
|
183
|
-
def
|
|
314
|
+
def _get_chats_by_ids(self, chat_ids: List[Text]) -> List[Dict]:
|
|
315
|
+
"""
|
|
316
|
+
Get chats by their IDs.
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
chat_ids (List[Text]): The IDs of the chats.
|
|
320
|
+
|
|
321
|
+
Returns:
|
|
322
|
+
List[Dict]: The chats data.
|
|
323
|
+
"""
|
|
324
|
+
chats = []
|
|
325
|
+
for chat_id in chat_ids:
|
|
326
|
+
chats.append(self._get_chat_by_id(chat_id))
|
|
327
|
+
|
|
328
|
+
return chats
|
|
329
|
+
|
|
330
|
+
def _get_messages_in_chat_by_ids(self, chat_id: Text, message_ids: List[Text]) -> List[Dict]:
|
|
331
|
+
"""
|
|
332
|
+
Get messages by their IDs and the ID of the chat that they belong to.
|
|
333
|
+
|
|
334
|
+
Args:
|
|
335
|
+
chat_id (Text): The ID of the chat that the messages belong to.
|
|
336
|
+
message_ids (List[Text]): The IDs of the messages.
|
|
337
|
+
|
|
338
|
+
Returns:
|
|
339
|
+
List[Dict]: The messages data.
|
|
340
|
+
"""
|
|
341
|
+
messages = []
|
|
342
|
+
for message_id in message_ids:
|
|
343
|
+
messages.append(self._get_message_in_chat_by_id(chat_id, message_id))
|
|
344
|
+
|
|
345
|
+
return messages
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class MSGraphAPITeamsApplicationPermissionsClient(MSGraphAPITeamsClient):
|
|
349
|
+
"""
|
|
350
|
+
The Microsoft Graph API client for the Microsoft Teams handler with application permissions.
|
|
351
|
+
This client is used for accessing the Microsoft Teams specific endpoints of the Microsoft Graph API.
|
|
352
|
+
Several common methods for submitting requests, fetching data, etc. are inherited from the base class.
|
|
353
|
+
"""
|
|
354
|
+
|
|
355
|
+
def _get_all_groups(self) -> List[Dict]:
|
|
356
|
+
"""
|
|
357
|
+
Get all groups related to Microsoft Teams.
|
|
358
|
+
|
|
359
|
+
Returns:
|
|
360
|
+
List[Dict]: The groups data.
|
|
361
|
+
"""
|
|
362
|
+
return self.fetch_data_json(
|
|
363
|
+
"/groups",
|
|
364
|
+
params={"$filter": "resourceProvisioningOptions/Any(x:x eq 'Team')"}
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
def _get_chat_by_id(self, chat_id: Text) -> Dict:
|
|
184
368
|
"""
|
|
185
369
|
Get a chat by its ID.
|
|
186
370
|
|
|
@@ -190,25 +374,82 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
190
374
|
Returns:
|
|
191
375
|
Dict: The chat data.
|
|
192
376
|
"""
|
|
193
|
-
return self.fetch_data_json(f"
|
|
377
|
+
return self.fetch_data_json(f"chats/{chat_id}")
|
|
194
378
|
|
|
195
|
-
def
|
|
379
|
+
def _get_all_chats(self, limit: int = None) -> List[Dict]:
|
|
196
380
|
"""
|
|
197
|
-
Get chats
|
|
381
|
+
Get all chats related to Microsoft Teams.
|
|
198
382
|
|
|
199
383
|
Args:
|
|
200
|
-
|
|
384
|
+
limit (int): The maximum number of chats to return.
|
|
201
385
|
|
|
202
386
|
Returns:
|
|
203
387
|
List[Dict]: The chats data.
|
|
204
388
|
"""
|
|
205
|
-
chats
|
|
206
|
-
for chat_id in chat_ids:
|
|
207
|
-
chats.append(self.get_chat_by_id(chat_id))
|
|
389
|
+
raise RuntimeError("Retrieving all chats is not supported with application permissions. Either use delegated permissions or provide a chat ID.")
|
|
208
390
|
|
|
209
|
-
|
|
391
|
+
def _get_message_in_chat_by_id(self, chat_id: Text, message_id: Text) -> Dict:
|
|
392
|
+
"""
|
|
393
|
+
Get a message by its ID and the ID of the chat that it belongs to.
|
|
394
|
+
|
|
395
|
+
Args:
|
|
396
|
+
chat_id (Text): The ID of the chat that the message belongs to.
|
|
397
|
+
message_id (Text): The ID of the message.
|
|
398
|
+
|
|
399
|
+
Returns:
|
|
400
|
+
Dict: The message data.
|
|
401
|
+
"""
|
|
402
|
+
return self.fetch_data_json(f"chats/{chat_id}/messages/{message_id}")
|
|
403
|
+
|
|
404
|
+
def _get_all_messages_in_chat(self, chat_id: Text, limit: int = None) -> List[Dict]:
|
|
405
|
+
"""
|
|
406
|
+
Get messages of a chat by its ID.
|
|
407
|
+
|
|
408
|
+
Args:
|
|
409
|
+
chat_id (Text): The ID of the chat.
|
|
210
410
|
|
|
211
|
-
|
|
411
|
+
Returns:
|
|
412
|
+
List[Dict]: The messages data.
|
|
413
|
+
"""
|
|
414
|
+
messages = []
|
|
415
|
+
for messages_batch in self.fetch_paginated_data(f"chats/{chat_id}/messages"):
|
|
416
|
+
messages += messages_batch
|
|
417
|
+
|
|
418
|
+
if limit and len(messages) >= limit:
|
|
419
|
+
break
|
|
420
|
+
|
|
421
|
+
return messages[:limit]
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPITeamsClient):
|
|
425
|
+
"""
|
|
426
|
+
The Microsoft Graph API client for the Microsoft Teams handler with delegated permissions.
|
|
427
|
+
This client is used for accessing the Microsoft Teams specific endpoints of the Microsoft Graph API.
|
|
428
|
+
Several common methods for submitting requests, fetching data, etc. are inherited from the base class.
|
|
429
|
+
"""
|
|
430
|
+
|
|
431
|
+
def _get_all_groups(self) -> List[Dict]:
|
|
432
|
+
"""
|
|
433
|
+
Get all groups that the signed in user is a member of.
|
|
434
|
+
|
|
435
|
+
Returns:
|
|
436
|
+
List[Dict]: The groups data.
|
|
437
|
+
"""
|
|
438
|
+
return self.fetch_data_json("me/joinedTeams")
|
|
439
|
+
|
|
440
|
+
def _get_chat_by_id(self, chat_id: Text) -> Dict:
|
|
441
|
+
"""
|
|
442
|
+
Get a chat by its ID.
|
|
443
|
+
|
|
444
|
+
Args:
|
|
445
|
+
chat_id (Text): The ID of the chat.
|
|
446
|
+
|
|
447
|
+
Returns:
|
|
448
|
+
Dict: The chat data.
|
|
449
|
+
"""
|
|
450
|
+
return self.fetch_data_json(f"/me/chats/{chat_id}")
|
|
451
|
+
|
|
452
|
+
def _get_all_chats(self, limit: int = None) -> List[Dict]:
|
|
212
453
|
"""
|
|
213
454
|
Get all chats of the signed in user.
|
|
214
455
|
|
|
@@ -227,7 +468,7 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
227
468
|
|
|
228
469
|
return chats[:limit]
|
|
229
470
|
|
|
230
|
-
def
|
|
471
|
+
def _get_message_in_chat_by_id(self, chat_id: Text, message_id: Text) -> Dict:
|
|
231
472
|
"""
|
|
232
473
|
Get a message by its ID and the ID of the chat that it belongs to.
|
|
233
474
|
|
|
@@ -240,24 +481,7 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
240
481
|
"""
|
|
241
482
|
return self.fetch_data_json(f"me/chats/{chat_id}/messages/{message_id}")
|
|
242
483
|
|
|
243
|
-
def
|
|
244
|
-
"""
|
|
245
|
-
Get messages by their IDs and the ID of the chat that they belong to.
|
|
246
|
-
|
|
247
|
-
Args:
|
|
248
|
-
chat_id (Text): The ID of the chat that the messages belong to.
|
|
249
|
-
message_ids (List[Text]): The IDs of the messages.
|
|
250
|
-
|
|
251
|
-
Returns:
|
|
252
|
-
List[Dict]: The messages data.
|
|
253
|
-
"""
|
|
254
|
-
messages = []
|
|
255
|
-
for message_id in message_ids:
|
|
256
|
-
messages.append(self.get_message_in_chat_by_id(chat_id, message_id))
|
|
257
|
-
|
|
258
|
-
return messages
|
|
259
|
-
|
|
260
|
-
def get_all_messages_in_chat(self, chat_id: Text, limit: int = None) -> List[Dict]:
|
|
484
|
+
def _get_all_messages_in_chat(self, chat_id: Text, limit: int = None) -> List[Dict]:
|
|
261
485
|
"""
|
|
262
486
|
Get messages of a chat by its ID.
|
|
263
487
|
|
|
@@ -275,4 +499,3 @@ class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
|
275
499
|
break
|
|
276
500
|
|
|
277
501
|
return messages[:limit]
|
|
278
|
-
|
|
@@ -7,7 +7,11 @@ from botframework.connector.auth import MicrosoftAppCredentials
|
|
|
7
7
|
import msal
|
|
8
8
|
from requests.exceptions import RequestException
|
|
9
9
|
|
|
10
|
-
from mindsdb.integrations.handlers.ms_teams_handler.ms_graph_api_teams_client import
|
|
10
|
+
from mindsdb.integrations.handlers.ms_teams_handler.ms_graph_api_teams_client import (
|
|
11
|
+
MSGraphAPIBaseClient,
|
|
12
|
+
MSGraphAPITeamsApplicationPermissionsClient,
|
|
13
|
+
MSGraphAPITeamsDelegatedPermissionsClient
|
|
14
|
+
)
|
|
11
15
|
from mindsdb.integrations.handlers.ms_teams_handler.ms_teams_tables import (
|
|
12
16
|
ChannelsTable, ChannelMessagesTable, ChatsTable, ChatMessagesTable, TeamsTable
|
|
13
17
|
)
|
|
@@ -15,17 +19,21 @@ from mindsdb.integrations.libs.response import (
|
|
|
15
19
|
HandlerStatusResponse as StatusResponse,
|
|
16
20
|
)
|
|
17
21
|
from mindsdb.integrations.libs.api_handler import APIChatHandler
|
|
18
|
-
from mindsdb.integrations.utilities.handlers.auth_utilities import
|
|
22
|
+
from mindsdb.integrations.utilities.handlers.auth_utilities import (
|
|
23
|
+
MSGraphAPIApplicationPermissionsManager,
|
|
24
|
+
MSGraphAPIDelegatedPermissionsManager
|
|
25
|
+
)
|
|
19
26
|
from mindsdb.integrations.utilities.handlers.auth_utilities.exceptions import AuthException
|
|
20
27
|
from mindsdb.interfaces.chatbot.types import ChatBotMessage
|
|
21
28
|
from mindsdb.utilities import log
|
|
22
29
|
|
|
30
|
+
|
|
23
31
|
logger = log.getLogger(__name__)
|
|
24
32
|
|
|
25
33
|
|
|
26
34
|
def chatbot_only(func):
|
|
27
35
|
def wrapper(self, *args, **kwargs):
|
|
28
|
-
if self.connection_data.get('
|
|
36
|
+
if self.connection_data.get('opertion_mode', 'datasource') != 'chatbot':
|
|
29
37
|
raise ValueError("This connection can only be used as a data source. Please use a chatbot connection by setting the 'mode' parameter to 'chat'.")
|
|
30
38
|
return func(self, *args, **kwargs)
|
|
31
39
|
return wrapper
|
|
@@ -62,7 +70,7 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
62
70
|
self.bot_id = None
|
|
63
71
|
self.conversation_id = None
|
|
64
72
|
|
|
65
|
-
def connect(self) -> Union[MicrosoftAppCredentials,
|
|
73
|
+
def connect(self) -> Union[MicrosoftAppCredentials, MSGraphAPIBaseClient]:
|
|
66
74
|
"""
|
|
67
75
|
Establishes a connection to the Microsoft Teams registered app or the Microsoft Graph API.
|
|
68
76
|
|
|
@@ -72,13 +80,9 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
72
80
|
if self.is_connected:
|
|
73
81
|
return self.connection
|
|
74
82
|
|
|
75
|
-
# The default mode is '
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
app_id=self.connection_data["client_id"],
|
|
79
|
-
password=self.connection_data["client_secret"]
|
|
80
|
-
)
|
|
81
|
-
else:
|
|
83
|
+
# The default operation mode is 'datasource'. This is used for data source connections.
|
|
84
|
+
operation_mode = self.connection_data.get('operation_mode', 'datasource')
|
|
85
|
+
if operation_mode == 'datasource':
|
|
82
86
|
# Initialize the token cache.
|
|
83
87
|
cache = msal.SerializableTokenCache()
|
|
84
88
|
|
|
@@ -92,13 +96,27 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
92
96
|
if cache_content:
|
|
93
97
|
cache.deserialize(cache_content)
|
|
94
98
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
# The default permissions mode is 'delegated'. This requires the user to sign in.
|
|
100
|
+
permission_mode = self.connection_data.get('permission_mode', 'delegated')
|
|
101
|
+
if permission_mode == 'delegated':
|
|
102
|
+
permissions_manager = MSGraphAPIDelegatedPermissionsManager(
|
|
103
|
+
client_id=self.connection_data['client_id'],
|
|
104
|
+
client_secret=self.connection_data['client_secret'],
|
|
105
|
+
tenant_id=self.connection_data['tenant_id'],
|
|
106
|
+
cache=cache,
|
|
107
|
+
code=self.connection_data.get('code')
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
elif permission_mode == 'application':
|
|
111
|
+
permissions_manager = MSGraphAPIApplicationPermissionsManager(
|
|
112
|
+
client_id=self.connection_data['client_id'],
|
|
113
|
+
client_secret=self.connection_data['client_secret'],
|
|
114
|
+
tenant_id=self.connection_data['tenant_id'],
|
|
115
|
+
cache=cache
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
else:
|
|
119
|
+
raise ValueError("The supported permission modes are 'delegated' and 'application'.")
|
|
102
120
|
|
|
103
121
|
access_token = permissions_manager.get_access_token()
|
|
104
122
|
|
|
@@ -106,7 +124,11 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
106
124
|
if cache.has_state_changed:
|
|
107
125
|
self.handler_storage.file_set(cache_file, cache.serialize().encode('utf-8'))
|
|
108
126
|
|
|
109
|
-
|
|
127
|
+
if permission_mode == 'delegated':
|
|
128
|
+
self.connection = MSGraphAPITeamsDelegatedPermissionsClient(access_token)
|
|
129
|
+
|
|
130
|
+
else:
|
|
131
|
+
self.connection = MSGraphAPITeamsApplicationPermissionsClient(access_token)
|
|
110
132
|
|
|
111
133
|
self._register_table('channels', ChannelsTable(self))
|
|
112
134
|
self._register_table('channel_messages', ChannelMessagesTable(self))
|
|
@@ -114,6 +136,15 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
114
136
|
self._register_table('chat_messages', ChatMessagesTable(self))
|
|
115
137
|
self._register_table('teams', TeamsTable(self))
|
|
116
138
|
|
|
139
|
+
elif operation_mode == 'chatbot':
|
|
140
|
+
self.connection = MicrosoftAppCredentials(
|
|
141
|
+
self.connection_data['app_id'],
|
|
142
|
+
self.connection_data['app_password']
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
else:
|
|
146
|
+
raise ValueError("The supported operation modes are 'datasource' and 'chatbot'.")
|
|
147
|
+
|
|
117
148
|
self.is_connected = True
|
|
118
149
|
|
|
119
150
|
return self.connection
|
|
@@ -129,8 +160,8 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
129
160
|
|
|
130
161
|
try:
|
|
131
162
|
connection = self.connect()
|
|
132
|
-
# A connection check against the Microsoft Graph API is run if the connection is in '
|
|
133
|
-
if self.connection_data.get('
|
|
163
|
+
# A connection check against the Microsoft Graph API is run if the connection is in 'datasource' mode.
|
|
164
|
+
if self.connection_data.get('operation_mode', 'datasource') == 'datasource' and connection.check_connection():
|
|
134
165
|
response.success = True
|
|
135
166
|
response.copy_storage = True
|
|
136
167
|
else:
|
|
@@ -33,10 +33,10 @@ class TeamsTable(APIResource):
|
|
|
33
33
|
targets (List[str]): The list of target columns to return.
|
|
34
34
|
"""
|
|
35
35
|
client: MSGraphAPITeamsDelegatedPermissionsClient = self.handler.connect()
|
|
36
|
-
teams = client.
|
|
36
|
+
teams = client.get_teams()
|
|
37
37
|
|
|
38
38
|
teams_df = pd.json_normalize(teams, sep="_")
|
|
39
|
-
teams_df = teams_df
|
|
39
|
+
teams_df = teams_df.reindex(columns=self.get_columns(), fill_value=None)
|
|
40
40
|
|
|
41
41
|
return teams_df
|
|
42
42
|
|
|
@@ -114,18 +114,7 @@ class ChannelsTable(APIResource):
|
|
|
114
114
|
|
|
115
115
|
condition.applied = True
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
if channel_ids:
|
|
119
|
-
channels = client.get_channels_in_group_by_ids(team_id, channel_ids)
|
|
120
|
-
|
|
121
|
-
else:
|
|
122
|
-
channels = client.get_all_channels_in_group(team_id)
|
|
123
|
-
|
|
124
|
-
elif channel_ids:
|
|
125
|
-
channels = client.get_channels_across_all_groups_by_ids(channel_ids)
|
|
126
|
-
|
|
127
|
-
else:
|
|
128
|
-
channels = client.get_all_channels_across_all_groups()
|
|
117
|
+
channels = client.get_channels(team_id, channel_ids)
|
|
129
118
|
|
|
130
119
|
channels_df = pd.json_normalize(channels, sep="_")
|
|
131
120
|
channels_df = channels_df[self.get_columns()]
|
|
@@ -218,11 +207,7 @@ class ChannelMessagesTable(APIResource):
|
|
|
218
207
|
if not group_id or not channel_id:
|
|
219
208
|
raise ValueError("The 'channelIdentity_teamId' and 'channelIdentity_channelId' columns are required.")
|
|
220
209
|
|
|
221
|
-
|
|
222
|
-
messages = client.get_messages_in_channel_by_ids(group_id, channel_id, message_ids)
|
|
223
|
-
|
|
224
|
-
else:
|
|
225
|
-
messages = client.get_all_messages_in_channel(group_id, channel_id, limit)
|
|
210
|
+
messages = client.get_channel_messages(group_id, channel_id, message_ids)
|
|
226
211
|
|
|
227
212
|
messages_df = pd.json_normalize(messages, sep="_")
|
|
228
213
|
messages_df = messages_df[self.get_columns()]
|
|
@@ -304,11 +289,7 @@ class ChatsTable(APIResource):
|
|
|
304
289
|
|
|
305
290
|
condition.applied = True
|
|
306
291
|
|
|
307
|
-
|
|
308
|
-
chats = client.get_chats_by_ids(chat_ids)
|
|
309
|
-
|
|
310
|
-
else:
|
|
311
|
-
chats = client.get_all_chats(limit)
|
|
292
|
+
chats = client.get_chats(chat_ids)
|
|
312
293
|
|
|
313
294
|
chats_df = pd.json_normalize(chats, sep="_")
|
|
314
295
|
chats_df = chats_df[self.get_columns()]
|
|
@@ -387,11 +368,7 @@ class ChatMessagesTable(APIResource):
|
|
|
387
368
|
if not chat_id:
|
|
388
369
|
raise ValueError("The 'chatId' column is required.")
|
|
389
370
|
|
|
390
|
-
|
|
391
|
-
messages = client.get_messages_in_chat_by_ids(chat_id, message_ids)
|
|
392
|
-
|
|
393
|
-
else:
|
|
394
|
-
messages = client.get_all_messages_in_chat(chat_id, limit)
|
|
371
|
+
messages = client.get_chat_messages(chat_id, message_ids)
|
|
395
372
|
|
|
396
373
|
messages_df = pd.json_normalize(messages, sep="_")
|
|
397
374
|
messages_df = messages_df[self.get_columns()]
|