MindsDB 25.2.4.0__py3-none-any.whl → 25.3.2.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 +16 -1
- mindsdb/api/executor/command_executor.py +1 -1
- mindsdb/api/executor/datahub/datanodes/system_tables.py +6 -1
- mindsdb/api/executor/planner/query_planner.py +6 -2
- mindsdb/api/executor/sql_query/steps/prepare_steps.py +2 -1
- mindsdb/api/executor/sql_query/steps/union_step.py +21 -24
- mindsdb/api/http/gui.py +5 -4
- mindsdb/api/http/initialize.py +19 -19
- mindsdb/api/mongo/classes/query_sql.py +2 -1
- mindsdb/api/mongo/responders/aggregate.py +2 -2
- mindsdb/api/mongo/responders/coll_stats.py +3 -2
- mindsdb/api/mongo/responders/db_stats.py +2 -1
- mindsdb/api/mongo/responders/insert.py +4 -2
- mindsdb/api/mysql/mysql_proxy/classes/fake_mysql_proxy/fake_mysql_proxy.py +2 -1
- mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +5 -4
- mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +2 -4
- mindsdb/integrations/handlers/autosklearn_handler/autosklearn_handler.py +1 -1
- mindsdb/integrations/handlers/gmail_handler/connection_args.py +2 -2
- mindsdb/integrations/handlers/gmail_handler/gmail_handler.py +19 -66
- mindsdb/integrations/handlers/gmail_handler/requirements.txt +0 -1
- mindsdb/integrations/handlers/google_calendar_handler/connection_args.py +15 -0
- mindsdb/integrations/handlers/google_calendar_handler/google_calendar_handler.py +31 -41
- mindsdb/integrations/handlers/google_calendar_handler/requirements.txt +0 -2
- mindsdb/integrations/handlers/jira_handler/__init__.py +1 -0
- mindsdb/integrations/handlers/jira_handler/jira_handler.py +22 -80
- mindsdb/integrations/handlers/pgvector_handler/pgvector_handler.py +3 -3
- mindsdb/integrations/handlers/slack_handler/slack_handler.py +2 -1
- mindsdb/integrations/handlers/youtube_handler/youtube_handler.py +2 -38
- mindsdb/integrations/libs/api_handler_generator.py +583 -0
- mindsdb/integrations/libs/llm/utils.py +2 -1
- mindsdb/integrations/utilities/handlers/auth_utilities/google/google_user_oauth_utilities.py +29 -38
- mindsdb/integrations/utilities/pydantic_utils.py +208 -0
- mindsdb/integrations/utilities/rag/pipelines/rag.py +11 -4
- mindsdb/integrations/utilities/rag/retrievers/sql_retriever.py +800 -135
- mindsdb/integrations/utilities/rag/settings.py +390 -152
- mindsdb/integrations/utilities/sql_utils.py +2 -1
- mindsdb/interfaces/agents/agents_controller.py +11 -7
- mindsdb/interfaces/agents/mindsdb_chat_model.py +4 -2
- mindsdb/interfaces/chatbot/chatbot_controller.py +9 -8
- mindsdb/interfaces/database/database.py +2 -1
- mindsdb/interfaces/database/projects.py +28 -2
- mindsdb/interfaces/jobs/jobs_controller.py +4 -1
- mindsdb/interfaces/model/model_controller.py +5 -2
- mindsdb/interfaces/skills/retrieval_tool.py +128 -39
- mindsdb/interfaces/skills/skill_tool.py +7 -7
- mindsdb/interfaces/skills/skills_controller.py +8 -4
- mindsdb/interfaces/storage/db.py +14 -0
- mindsdb/interfaces/storage/json.py +59 -0
- mindsdb/interfaces/storage/model_fs.py +85 -3
- mindsdb/interfaces/triggers/triggers_controller.py +2 -1
- mindsdb/migrations/versions/2022-10-14_43c52d23845a_projects.py +17 -3
- mindsdb/migrations/versions/2025-02-14_4521dafe89ab_added_encrypted_content_to_json_storage.py +29 -0
- mindsdb/migrations/versions/2025-02-19_11347c213b36_added_metadata_to_projects.py +41 -0
- mindsdb/utilities/config.py +6 -2
- mindsdb/utilities/functions.py +11 -0
- {MindsDB-25.2.4.0.dist-info → mindsdb-25.3.2.0.dist-info}/METADATA +219 -222
- {MindsDB-25.2.4.0.dist-info → mindsdb-25.3.2.0.dist-info}/RECORD +61 -60
- {MindsDB-25.2.4.0.dist-info → mindsdb-25.3.2.0.dist-info}/WHEEL +1 -1
- mindsdb/integrations/handlers/gmail_handler/utils.py +0 -45
- mindsdb/integrations/handlers/jira_handler/jira_table.py +0 -172
- mindsdb/integrations/handlers/jira_handler/requirements.txt +0 -1
- {MindsDB-25.2.4.0.dist-info → mindsdb-25.3.2.0.dist-info}/LICENSE +0 -0
- {MindsDB-25.2.4.0.dist-info → mindsdb-25.3.2.0.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from shutil import copyfile
|
|
3
|
-
|
|
4
|
-
import requests
|
|
5
2
|
|
|
6
3
|
from mindsdb.integrations.libs.response import (
|
|
7
4
|
HandlerStatusResponse as StatusResponse,
|
|
@@ -15,31 +12,28 @@ from mindsdb.utilities import log
|
|
|
15
12
|
from mindsdb_sql_parser import parse_sql
|
|
16
13
|
from mindsdb.utilities.config import Config
|
|
17
14
|
|
|
18
|
-
import os
|
|
19
15
|
import time
|
|
20
16
|
from typing import List
|
|
21
17
|
import pandas as pd
|
|
22
18
|
|
|
23
|
-
from google.auth.transport.requests import Request
|
|
24
|
-
from google.oauth2.credentials import Credentials
|
|
25
|
-
from google_auth_oauthlib.flow import Flow
|
|
26
19
|
from googleapiclient.discovery import build
|
|
27
20
|
from googleapiclient.errors import HttpError
|
|
28
21
|
from email.message import EmailMessage
|
|
29
22
|
|
|
30
23
|
from base64 import urlsafe_b64encode, urlsafe_b64decode
|
|
31
24
|
|
|
32
|
-
from .
|
|
25
|
+
from mindsdb.integrations.utilities.handlers.auth_utilities import GoogleUserOAuth2Manager
|
|
26
|
+
from mindsdb.integrations.utilities.handlers.auth_utilities.exceptions import AuthException
|
|
33
27
|
|
|
34
|
-
DEFAULT_SCOPES = [
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
DEFAULT_SCOPES = [
|
|
29
|
+
'https://www.googleapis.com/auth/gmail.compose',
|
|
30
|
+
'https://www.googleapis.com/auth/gmail.readonly',
|
|
31
|
+
'https://www.googleapis.com/auth/gmail.modify'
|
|
32
|
+
]
|
|
37
33
|
|
|
38
34
|
logger = log.getLogger(__name__)
|
|
39
35
|
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
|
|
43
37
|
class EmailsTable(APITable):
|
|
44
38
|
"""Implementation for the emails table for Gmail"""
|
|
45
39
|
|
|
@@ -283,6 +277,14 @@ class GmailHandler(APIHandler):
|
|
|
283
277
|
super().__init__(name)
|
|
284
278
|
self.connection_args = kwargs.get('connection_data', {})
|
|
285
279
|
|
|
280
|
+
self.token_file = None
|
|
281
|
+
self.max_page_size = 500
|
|
282
|
+
self.max_batch_size = 100
|
|
283
|
+
self.service = None
|
|
284
|
+
self.is_connected = False
|
|
285
|
+
|
|
286
|
+
self.handler_storage = kwargs['handler_storage']
|
|
287
|
+
|
|
286
288
|
self.credentials_url = self.connection_args.get('credentials_url', None)
|
|
287
289
|
self.credentials_file = self.connection_args.get('credentials_file', None)
|
|
288
290
|
if self.connection_args.get('credentials'):
|
|
@@ -298,63 +300,11 @@ class GmailHandler(APIHandler):
|
|
|
298
300
|
self.credentials_url = secret_url
|
|
299
301
|
|
|
300
302
|
self.scopes = self.connection_args.get('scopes', DEFAULT_SCOPES)
|
|
301
|
-
self.token_file = None
|
|
302
|
-
self.max_page_size = 500
|
|
303
|
-
self.max_batch_size = 100
|
|
304
|
-
self.service = None
|
|
305
|
-
self.is_connected = False
|
|
306
|
-
|
|
307
|
-
self.handler_storage = kwargs['handler_storage']
|
|
308
303
|
|
|
309
304
|
emails = EmailsTable(self)
|
|
310
305
|
self.emails = emails
|
|
311
306
|
self._register_table('emails', emails)
|
|
312
307
|
|
|
313
|
-
def _download_secret_file(self, secret_file):
|
|
314
|
-
# Giving more priority to the S3 file
|
|
315
|
-
if self.credentials_url:
|
|
316
|
-
response = requests.get(self.credentials_url)
|
|
317
|
-
if response.status_code == 200:
|
|
318
|
-
with open(secret_file, 'w') as creds:
|
|
319
|
-
creds.write(response.text)
|
|
320
|
-
return True
|
|
321
|
-
else:
|
|
322
|
-
logger.error("Failed to get credentials from S3", response.status_code)
|
|
323
|
-
|
|
324
|
-
if self.credentials_file and os.path.isfile(self.credentials_file):
|
|
325
|
-
copyfile(self.credentials_file, secret_file)
|
|
326
|
-
return True
|
|
327
|
-
return False
|
|
328
|
-
|
|
329
|
-
def create_connection(self):
|
|
330
|
-
creds = None
|
|
331
|
-
|
|
332
|
-
# Get the current dir, we'll check for Token & Creds files in this dir
|
|
333
|
-
curr_dir = self.handler_storage.folder_get('config')
|
|
334
|
-
|
|
335
|
-
creds_file = os.path.join(curr_dir, 'creds.json')
|
|
336
|
-
secret_file = os.path.join(curr_dir, 'secret.json')
|
|
337
|
-
|
|
338
|
-
if os.path.isfile(creds_file):
|
|
339
|
-
creds = Credentials.from_authorized_user_file(creds_file, self.scopes)
|
|
340
|
-
|
|
341
|
-
if not creds or not creds.valid:
|
|
342
|
-
if creds and creds.expired and creds.refresh_token:
|
|
343
|
-
creds.refresh(Request())
|
|
344
|
-
|
|
345
|
-
if self._download_secret_file(secret_file):
|
|
346
|
-
# save to storage
|
|
347
|
-
self.handler_storage.folder_sync('config')
|
|
348
|
-
else:
|
|
349
|
-
raise ValueError('No valid Gmail Credentials filepath or S3 url found.')
|
|
350
|
-
|
|
351
|
-
creds = google_auth_flow(secret_file, self.scopes, self.connection_args.get('code'))
|
|
352
|
-
|
|
353
|
-
save_creds_to_file(creds, creds_file)
|
|
354
|
-
self.handler_storage.folder_sync('config')
|
|
355
|
-
|
|
356
|
-
return build('gmail', 'v1', credentials=creds)
|
|
357
|
-
|
|
358
308
|
def connect(self):
|
|
359
309
|
"""Authenticate with the Gmail API using the credentials file.
|
|
360
310
|
|
|
@@ -366,7 +316,10 @@ class GmailHandler(APIHandler):
|
|
|
366
316
|
if self.is_connected and self.service is not None:
|
|
367
317
|
return self.service
|
|
368
318
|
|
|
369
|
-
self.
|
|
319
|
+
google_oauth2_manager = GoogleUserOAuth2Manager(self.handler_storage, self.scopes, self.credentials_file, self.credentials_url, self.connection_args.get('code'))
|
|
320
|
+
creds = google_oauth2_manager.get_oauth2_credentials()
|
|
321
|
+
|
|
322
|
+
self.service = build('gmail', 'v1', credentials=creds)
|
|
370
323
|
|
|
371
324
|
self.is_connected = True
|
|
372
325
|
return self.service
|
|
@@ -4,9 +4,24 @@ from mindsdb.integrations.libs.const import HANDLER_CONNECTION_ARG_TYPE as ARG_T
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
connection_args = OrderedDict(
|
|
7
|
+
credentials_url={
|
|
8
|
+
'type': ARG_TYPE.STR,
|
|
9
|
+
'description': 'URL to Service Account Keys',
|
|
10
|
+
'label': 'URL to Service Account Keys',
|
|
11
|
+
},
|
|
12
|
+
credentials_file={
|
|
13
|
+
'type': ARG_TYPE.STR,
|
|
14
|
+
'description': 'Location of Service Account Keys',
|
|
15
|
+
'label': 'Path to Service Account Keys',
|
|
16
|
+
},
|
|
7
17
|
credentials={
|
|
8
18
|
'type': ARG_TYPE.PATH,
|
|
9
19
|
'description': 'Service Account Keys',
|
|
10
20
|
'label': 'Upload Service Account Keys',
|
|
11
21
|
},
|
|
22
|
+
code={
|
|
23
|
+
'type': ARG_TYPE.STR,
|
|
24
|
+
'description': 'Code After Authorisation',
|
|
25
|
+
'label': 'Code After Authorisation',
|
|
26
|
+
},
|
|
12
27
|
)
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
1
|
import pandas as pd
|
|
4
|
-
from google.auth.transport.requests import Request
|
|
5
|
-
from google.oauth2.credentials import Credentials
|
|
6
2
|
from googleapiclient.discovery import build
|
|
7
3
|
|
|
8
4
|
from mindsdb.api.executor.data_types.response_type import RESPONSE_TYPE
|
|
@@ -11,13 +7,21 @@ from mindsdb.integrations.libs.response import (
|
|
|
11
7
|
HandlerStatusResponse as StatusResponse,
|
|
12
8
|
HandlerResponse as Response,
|
|
13
9
|
)
|
|
10
|
+
from mindsdb.utilities.config import Config
|
|
14
11
|
from mindsdb.utilities import log
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
from mindsdb.integrations.handlers.gmail_handler.utils import AuthException, google_auth_flow, save_creds_to_file
|
|
12
|
+
from mindsdb.integrations.utilities.handlers.auth_utilities import GoogleUserOAuth2Manager
|
|
13
|
+
from mindsdb.integrations.utilities.handlers.auth_utilities.exceptions import AuthException
|
|
18
14
|
|
|
19
15
|
from .google_calendar_tables import GoogleCalendarEventsTable
|
|
20
16
|
|
|
17
|
+
DEFAULT_SCOPES = [
|
|
18
|
+
'https://www.googleapis.com/auth/calendar',
|
|
19
|
+
'https://www.googleapis.com/auth/calendar.events',
|
|
20
|
+
'https://www.googleapis.com/auth/calendar.readonly'
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
logger = log.getLogger(__name__)
|
|
24
|
+
|
|
21
25
|
|
|
22
26
|
class GoogleCalendarHandler(APIHandler):
|
|
23
27
|
"""
|
|
@@ -35,20 +39,29 @@ class GoogleCalendarHandler(APIHandler):
|
|
|
35
39
|
events (GoogleCalendarEventsTable): The `GoogleCalendarEventsTable` object for interacting with the events table.
|
|
36
40
|
"""
|
|
37
41
|
super().__init__(name)
|
|
42
|
+
self.connection_data = kwargs.get('connection_data', {})
|
|
38
43
|
|
|
39
|
-
self.token = None
|
|
40
44
|
self.service = None
|
|
41
|
-
self.connection_data = kwargs.get('connection_data', {})
|
|
42
|
-
self.credentials_file = self.connection_data['credentials']
|
|
43
|
-
self.scopes = [
|
|
44
|
-
'https://www.googleapis.com/auth/calendar',
|
|
45
|
-
'https://www.googleapis.com/auth/calendar.events',
|
|
46
|
-
'https://www.googleapis.com/auth/calendar.readonly'
|
|
47
|
-
]
|
|
48
45
|
self.is_connected = False
|
|
49
46
|
|
|
50
47
|
self.handler_storage = kwargs['handler_storage']
|
|
51
48
|
|
|
49
|
+
self.credentials_url = self.connection_data.get('credentials_url', None)
|
|
50
|
+
self.credentials_file = self.connection_data.get('credentials_file', None)
|
|
51
|
+
if self.connection_data.get('credentials'):
|
|
52
|
+
self.credentials_file = self.connection_data.pop('credentials')
|
|
53
|
+
if not self.credentials_file and not self.credentials_url:
|
|
54
|
+
# try to get from config
|
|
55
|
+
gcalendar_config = Config().get('handlers', {}).get('youtube', {})
|
|
56
|
+
secret_file = gcalendar_config.get('credentials_file')
|
|
57
|
+
secret_url = gcalendar_config.get('credentials_url')
|
|
58
|
+
if secret_file:
|
|
59
|
+
self.credentials_file = secret_file
|
|
60
|
+
elif secret_url:
|
|
61
|
+
self.credentials_url = secret_url
|
|
62
|
+
|
|
63
|
+
self.scopes = self.connection_data.get('scopes', DEFAULT_SCOPES)
|
|
64
|
+
|
|
52
65
|
events = GoogleCalendarEventsTable(self)
|
|
53
66
|
self.events = events
|
|
54
67
|
self._register_table('events', events)
|
|
@@ -64,32 +77,8 @@ class GoogleCalendarHandler(APIHandler):
|
|
|
64
77
|
if self.is_connected is True:
|
|
65
78
|
return self.service
|
|
66
79
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
curr_dir = self.handler_storage.folder_get('config')
|
|
70
|
-
|
|
71
|
-
creds_file = None
|
|
72
|
-
try:
|
|
73
|
-
creds_file = os.path.join(curr_dir, 'secret.json')
|
|
74
|
-
except Exception:
|
|
75
|
-
pass
|
|
76
|
-
|
|
77
|
-
creds = None
|
|
78
|
-
if os.path.isfile(creds_file):
|
|
79
|
-
creds = Credentials.from_authorized_user_file(creds_file, self.scopes)
|
|
80
|
-
|
|
81
|
-
if not creds or not creds.valid:
|
|
82
|
-
if creds and creds.expired and creds.refresh_token:
|
|
83
|
-
creds.refresh(Request())
|
|
84
|
-
|
|
85
|
-
save_creds_to_file(creds, creds_file)
|
|
86
|
-
self.handler_storage.folder_sync('config')
|
|
87
|
-
|
|
88
|
-
else:
|
|
89
|
-
creds = google_auth_flow(secret_file, self.scopes, self.connection_data.get('code'))
|
|
90
|
-
|
|
91
|
-
save_creds_to_file(creds, creds_file)
|
|
92
|
-
self.handler_storage.folder_sync('config')
|
|
80
|
+
google_oauth2_manager = GoogleUserOAuth2Manager(self.handler_storage, self.scopes, self.credentials_file, self.credentials_url, self.connection_data.get('code'))
|
|
81
|
+
creds = google_oauth2_manager.get_oauth2_credentials()
|
|
93
82
|
|
|
94
83
|
self.service = build('calendar', 'v3', credentials=creds)
|
|
95
84
|
return self.service
|
|
@@ -106,6 +95,7 @@ class GoogleCalendarHandler(APIHandler):
|
|
|
106
95
|
try:
|
|
107
96
|
self.connect()
|
|
108
97
|
response.success = True
|
|
98
|
+
response.copy_storage = True
|
|
109
99
|
|
|
110
100
|
except AuthException as error:
|
|
111
101
|
response.error_message = str(error)
|
|
@@ -1,23 +1,15 @@
|
|
|
1
|
-
from mindsdb.integrations.handlers.jira_handler.jira_table import JiraProjectsTable
|
|
2
1
|
from mindsdb.integrations.libs.api_handler import APIHandler
|
|
3
2
|
from mindsdb.integrations.libs.response import (
|
|
4
3
|
HandlerStatusResponse as StatusResponse,
|
|
5
4
|
)
|
|
6
5
|
from mindsdb.utilities import log
|
|
7
|
-
from
|
|
8
|
-
|
|
9
|
-
from atlassian import Jira
|
|
10
|
-
from typing import Optional
|
|
11
|
-
import requests
|
|
6
|
+
from mindsdb.integrations.libs.api_handler_generator import APIResourceGenerator
|
|
12
7
|
|
|
13
8
|
|
|
14
9
|
logger = log.getLogger(__name__)
|
|
15
10
|
|
|
16
|
-
class JiraHandler(APIHandler):
|
|
17
|
-
"""
|
|
18
|
-
This handler handles connection and execution of the Airtable statements.
|
|
19
|
-
"""
|
|
20
11
|
|
|
12
|
+
class JiraHandler(APIHandler):
|
|
21
13
|
|
|
22
14
|
def __init__(self, name=None, **kwargs):
|
|
23
15
|
"""
|
|
@@ -30,64 +22,38 @@ class JiraHandler(APIHandler):
|
|
|
30
22
|
super().__init__(name)
|
|
31
23
|
self.connection_data = kwargs.get("connection_data", {})
|
|
32
24
|
|
|
33
|
-
self.parser = parse_sql
|
|
34
|
-
self.dialect = 'jira'
|
|
35
|
-
self.kwargs = kwargs
|
|
36
25
|
self.connection = None
|
|
37
26
|
self.is_connected = False
|
|
38
27
|
|
|
28
|
+
# todo store parsed data in files
|
|
29
|
+
|
|
30
|
+
self.api_resource_generator = APIResourceGenerator(
|
|
31
|
+
"https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json",
|
|
32
|
+
self.connection_data,
|
|
33
|
+
url_base='/rest/api/3/',
|
|
34
|
+
options={
|
|
35
|
+
'offset_param': ['startAt', 'offset'],
|
|
36
|
+
'total_column': ['totalEntryCount', 'total'],
|
|
37
|
+
'check_connection_table': 'myself'
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
resource_tables = self.api_resource_generator.generate_api_resources(self)
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
for table_name, resource in resource_tables.items():
|
|
44
|
+
self._register_table(table_name, resource)
|
|
42
45
|
|
|
43
46
|
def __del__(self):
|
|
44
47
|
if self.is_connected is True:
|
|
45
48
|
self.disconnect()
|
|
46
49
|
|
|
47
|
-
def connect(self)
|
|
50
|
+
def connect(self):
|
|
48
51
|
"""
|
|
49
52
|
Set up the connection required by the handler.
|
|
50
53
|
Returns:
|
|
51
54
|
HandlerStatusResponse
|
|
52
55
|
"""
|
|
53
|
-
|
|
54
|
-
if self.is_connected is True:
|
|
55
|
-
return self.connection
|
|
56
|
-
|
|
57
|
-
s = requests.Session()
|
|
58
|
-
if self.connection_data.get("cloud", False):
|
|
59
|
-
params = {
|
|
60
|
-
"cloud": True,
|
|
61
|
-
"username": self.connection_data['jira_username'],
|
|
62
|
-
"password": self.connection_data['jira_api_token'],
|
|
63
|
-
"url": self.connection_data['jira_url'],
|
|
64
|
-
}
|
|
65
|
-
else:
|
|
66
|
-
params = {
|
|
67
|
-
"cloud": False,
|
|
68
|
-
"url": self.connection_data['jira_url'],
|
|
69
|
-
"session": s
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
s.headers['Authorization'] = f"Bearer {self.connection_data['jira_api_token']}"
|
|
73
|
-
|
|
74
|
-
self.connection = Jira(**params)
|
|
75
|
-
self.is_connected = True
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return self.connection
|
|
79
|
-
|
|
80
|
-
def disconnect(self):
|
|
81
|
-
"""
|
|
82
|
-
Close any existing connections.
|
|
83
|
-
"""
|
|
84
|
-
|
|
85
|
-
if self.is_connected is False:
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
self.connection.close()
|
|
89
|
-
self.is_connected = False
|
|
90
|
-
return self.is_connected
|
|
56
|
+
return
|
|
91
57
|
|
|
92
58
|
def check_connection(self) -> StatusResponse:
|
|
93
59
|
"""
|
|
@@ -97,37 +63,13 @@ class JiraHandler(APIHandler):
|
|
|
97
63
|
"""
|
|
98
64
|
|
|
99
65
|
response = StatusResponse(False)
|
|
100
|
-
|
|
101
|
-
|
|
66
|
+
|
|
102
67
|
try:
|
|
103
|
-
self.
|
|
68
|
+
self.api_resource_generator.check_connection()
|
|
104
69
|
response.success = True
|
|
105
70
|
except Exception as e:
|
|
106
71
|
logger.error(f"Error connecting to Jira API: {e}!")
|
|
107
72
|
response.error_message = e
|
|
108
73
|
|
|
109
74
|
self.is_connected = response.success
|
|
110
|
-
|
|
111
75
|
return response
|
|
112
|
-
|
|
113
|
-
def native_query(self, query: str) -> StatusResponse:
|
|
114
|
-
"""Receive and process a raw query.
|
|
115
|
-
Parameters
|
|
116
|
-
----------
|
|
117
|
-
query : str
|
|
118
|
-
query in a native format
|
|
119
|
-
Returns
|
|
120
|
-
-------
|
|
121
|
-
StatusResponse
|
|
122
|
-
Request status
|
|
123
|
-
"""
|
|
124
|
-
ast = parse_sql(query)
|
|
125
|
-
return self.query(ast)
|
|
126
|
-
|
|
127
|
-
def construct_jql(self):
|
|
128
|
-
"""construct jql & returns it to JiraProjectsTable class
|
|
129
|
-
Returns
|
|
130
|
-
-------
|
|
131
|
-
Str
|
|
132
|
-
"""
|
|
133
|
-
return 'project = ' + str(self.connection_data['project'])
|
|
@@ -27,7 +27,7 @@ logger = log.getLogger(__name__)
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
# todo Issue #7316 add support for different indexes and search algorithms e.g. cosine similarity or L2 norm
|
|
30
|
-
class PgVectorHandler(
|
|
30
|
+
class PgVectorHandler(PostgresHandler, VectorStoreHandler):
|
|
31
31
|
"""This handler handles connection and execution of the PostgreSQL with pgvector extension statements."""
|
|
32
32
|
|
|
33
33
|
name = "pgvector"
|
|
@@ -64,11 +64,11 @@ class PgVectorHandler(VectorStoreHandler, PostgresHandler):
|
|
|
64
64
|
return Response(RESPONSE_TYPE.OK)
|
|
65
65
|
return super().get_tables()
|
|
66
66
|
|
|
67
|
-
def native_query(self, query) -> Response:
|
|
67
|
+
def native_query(self, query, params=None) -> Response:
|
|
68
68
|
# Prevent execute native queries
|
|
69
69
|
if self._is_shared_db:
|
|
70
70
|
return Response(RESPONSE_TYPE.OK)
|
|
71
|
-
return super().native_query(query)
|
|
71
|
+
return super().native_query(query, params=params)
|
|
72
72
|
|
|
73
73
|
def raw_query(self, query, params=None) -> Response:
|
|
74
74
|
resp = super().native_query(query, params)
|
|
@@ -267,7 +267,8 @@ class SlackHandler(APIChatHandler):
|
|
|
267
267
|
user_info = web_connection.auth_test().data
|
|
268
268
|
return user_info['bot_id']
|
|
269
269
|
|
|
270
|
-
def subscribe(self, stop_event: threading.Event, callback: Callable, table_name: Text
|
|
270
|
+
def subscribe(self, stop_event: threading.Event, callback: Callable, table_name: Text = 'messages',
|
|
271
|
+
columns: List = None, **kwargs: Any) -> None:
|
|
271
272
|
"""
|
|
272
273
|
Subscribes to the Slack API using the Socket Mode for real-time responses to messages.
|
|
273
274
|
|
|
@@ -10,9 +10,7 @@ from mindsdb.integrations.libs.response import (
|
|
|
10
10
|
from mindsdb.utilities import log
|
|
11
11
|
from mindsdb_sql_parser import parse_sql
|
|
12
12
|
|
|
13
|
-
from collections import OrderedDict
|
|
14
13
|
from mindsdb.utilities.config import Config
|
|
15
|
-
from mindsdb.integrations.libs.const import HANDLER_CONNECTION_ARG_TYPE as ARG_TYPE
|
|
16
14
|
|
|
17
15
|
from googleapiclient.discovery import build
|
|
18
16
|
|
|
@@ -38,12 +36,10 @@ class YoutubeHandler(APIHandler):
|
|
|
38
36
|
name of a handler instance
|
|
39
37
|
"""
|
|
40
38
|
super().__init__(name)
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
self.connection_data = kwargs.get("connection_data", {})
|
|
40
|
+
self.kwargs = kwargs
|
|
43
41
|
|
|
44
42
|
self.parser = parse_sql
|
|
45
|
-
self.connection_data = connection_data
|
|
46
|
-
self.kwargs = kwargs
|
|
47
43
|
self.connection = None
|
|
48
44
|
self.is_connected = False
|
|
49
45
|
|
|
@@ -104,7 +100,6 @@ class YoutubeHandler(APIHandler):
|
|
|
104
100
|
Status confirmation
|
|
105
101
|
"""
|
|
106
102
|
response = StatusResponse(False)
|
|
107
|
-
need_to_close = self.is_connected is False
|
|
108
103
|
|
|
109
104
|
try:
|
|
110
105
|
self.connect()
|
|
@@ -131,34 +126,3 @@ class YoutubeHandler(APIHandler):
|
|
|
131
126
|
"""
|
|
132
127
|
ast = parse_sql(query)
|
|
133
128
|
return self.query(ast)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
connection_args = OrderedDict(
|
|
137
|
-
youtube_access_token={
|
|
138
|
-
"type": ARG_TYPE.STR,
|
|
139
|
-
"description": "API Key",
|
|
140
|
-
"label": "API Key",
|
|
141
|
-
},
|
|
142
|
-
credentials_url={
|
|
143
|
-
'type': ARG_TYPE.STR,
|
|
144
|
-
'description': 'URL to OAuth2 Credentials',
|
|
145
|
-
'label': 'URL to OAuth2 Credentials',
|
|
146
|
-
},
|
|
147
|
-
credentials_file={
|
|
148
|
-
'type': ARG_TYPE.STR,
|
|
149
|
-
'description': 'Location of OAuth2 Credentials',
|
|
150
|
-
'label': 'Location of OAuth2 Credentials',
|
|
151
|
-
},
|
|
152
|
-
credentials={
|
|
153
|
-
'type': ARG_TYPE.PATH,
|
|
154
|
-
'description': 'OAuth2 Credentials',
|
|
155
|
-
'label': 'Upload OAuth2 Credentials',
|
|
156
|
-
},
|
|
157
|
-
code={
|
|
158
|
-
'type': ARG_TYPE.STR,
|
|
159
|
-
'description': 'Authentication Code',
|
|
160
|
-
'label': 'Authentication Code',
|
|
161
|
-
}
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
connection_args_example = OrderedDict(youtube_api_token="<your-youtube-api-token>")
|