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.

Files changed (64) hide show
  1. mindsdb/__about__.py +1 -1
  2. mindsdb/__main__.py +16 -1
  3. mindsdb/api/executor/command_executor.py +1 -1
  4. mindsdb/api/executor/datahub/datanodes/system_tables.py +6 -1
  5. mindsdb/api/executor/planner/query_planner.py +6 -2
  6. mindsdb/api/executor/sql_query/steps/prepare_steps.py +2 -1
  7. mindsdb/api/executor/sql_query/steps/union_step.py +21 -24
  8. mindsdb/api/http/gui.py +5 -4
  9. mindsdb/api/http/initialize.py +19 -19
  10. mindsdb/api/mongo/classes/query_sql.py +2 -1
  11. mindsdb/api/mongo/responders/aggregate.py +2 -2
  12. mindsdb/api/mongo/responders/coll_stats.py +3 -2
  13. mindsdb/api/mongo/responders/db_stats.py +2 -1
  14. mindsdb/api/mongo/responders/insert.py +4 -2
  15. mindsdb/api/mysql/mysql_proxy/classes/fake_mysql_proxy/fake_mysql_proxy.py +2 -1
  16. mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +5 -4
  17. mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +2 -4
  18. mindsdb/integrations/handlers/autosklearn_handler/autosklearn_handler.py +1 -1
  19. mindsdb/integrations/handlers/gmail_handler/connection_args.py +2 -2
  20. mindsdb/integrations/handlers/gmail_handler/gmail_handler.py +19 -66
  21. mindsdb/integrations/handlers/gmail_handler/requirements.txt +0 -1
  22. mindsdb/integrations/handlers/google_calendar_handler/connection_args.py +15 -0
  23. mindsdb/integrations/handlers/google_calendar_handler/google_calendar_handler.py +31 -41
  24. mindsdb/integrations/handlers/google_calendar_handler/requirements.txt +0 -2
  25. mindsdb/integrations/handlers/jira_handler/__init__.py +1 -0
  26. mindsdb/integrations/handlers/jira_handler/jira_handler.py +22 -80
  27. mindsdb/integrations/handlers/pgvector_handler/pgvector_handler.py +3 -3
  28. mindsdb/integrations/handlers/slack_handler/slack_handler.py +2 -1
  29. mindsdb/integrations/handlers/youtube_handler/youtube_handler.py +2 -38
  30. mindsdb/integrations/libs/api_handler_generator.py +583 -0
  31. mindsdb/integrations/libs/llm/utils.py +2 -1
  32. mindsdb/integrations/utilities/handlers/auth_utilities/google/google_user_oauth_utilities.py +29 -38
  33. mindsdb/integrations/utilities/pydantic_utils.py +208 -0
  34. mindsdb/integrations/utilities/rag/pipelines/rag.py +11 -4
  35. mindsdb/integrations/utilities/rag/retrievers/sql_retriever.py +800 -135
  36. mindsdb/integrations/utilities/rag/settings.py +390 -152
  37. mindsdb/integrations/utilities/sql_utils.py +2 -1
  38. mindsdb/interfaces/agents/agents_controller.py +11 -7
  39. mindsdb/interfaces/agents/mindsdb_chat_model.py +4 -2
  40. mindsdb/interfaces/chatbot/chatbot_controller.py +9 -8
  41. mindsdb/interfaces/database/database.py +2 -1
  42. mindsdb/interfaces/database/projects.py +28 -2
  43. mindsdb/interfaces/jobs/jobs_controller.py +4 -1
  44. mindsdb/interfaces/model/model_controller.py +5 -2
  45. mindsdb/interfaces/skills/retrieval_tool.py +128 -39
  46. mindsdb/interfaces/skills/skill_tool.py +7 -7
  47. mindsdb/interfaces/skills/skills_controller.py +8 -4
  48. mindsdb/interfaces/storage/db.py +14 -0
  49. mindsdb/interfaces/storage/json.py +59 -0
  50. mindsdb/interfaces/storage/model_fs.py +85 -3
  51. mindsdb/interfaces/triggers/triggers_controller.py +2 -1
  52. mindsdb/migrations/versions/2022-10-14_43c52d23845a_projects.py +17 -3
  53. mindsdb/migrations/versions/2025-02-14_4521dafe89ab_added_encrypted_content_to_json_storage.py +29 -0
  54. mindsdb/migrations/versions/2025-02-19_11347c213b36_added_metadata_to_projects.py +41 -0
  55. mindsdb/utilities/config.py +6 -2
  56. mindsdb/utilities/functions.py +11 -0
  57. {MindsDB-25.2.4.0.dist-info → mindsdb-25.3.2.0.dist-info}/METADATA +219 -222
  58. {MindsDB-25.2.4.0.dist-info → mindsdb-25.3.2.0.dist-info}/RECORD +61 -60
  59. {MindsDB-25.2.4.0.dist-info → mindsdb-25.3.2.0.dist-info}/WHEEL +1 -1
  60. mindsdb/integrations/handlers/gmail_handler/utils.py +0 -45
  61. mindsdb/integrations/handlers/jira_handler/jira_table.py +0 -172
  62. mindsdb/integrations/handlers/jira_handler/requirements.txt +0 -1
  63. {MindsDB-25.2.4.0.dist-info → mindsdb-25.3.2.0.dist-info}/LICENSE +0 -0
  64. {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 .utils import AuthException, google_auth_flow, save_creds_to_file
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 = ['https://www.googleapis.com/auth/gmail.compose',
35
- 'https://www.googleapis.com/auth/gmail.readonly',
36
- 'https://www.googleapis.com/auth/gmail.modify']
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.service = self.create_connection()
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
@@ -1,2 +1 @@
1
1
  google-api-python-client
2
- google-auth-httplib2
@@ -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
- logger = log.getLogger(__name__)
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
- secret_file = self.credentials_file
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,3 +1 @@
1
1
  google-api-python-client
2
- google-auth-httplib2
3
- -r mindsdb/integrations/handlers/gmail_handler/requirements.txt
@@ -4,6 +4,7 @@ from .__about__ import __version__ as version, __description__ as description
4
4
  try:
5
5
  from .jira_handler import JiraHandler as Handler
6
6
  import_error = None
7
+
7
8
  except Exception as e:
8
9
  Handler = None
9
10
  import_error = e
@@ -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 mindsdb_sql_parser import parse_sql
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
- jira_projects_data = JiraProjectsTable(self)
41
- self._register_table("project", jira_projects_data)
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) -> StatusResponse:
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
- need_to_close = self.is_connected is False
101
-
66
+
102
67
  try:
103
- self.connect()
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(VectorStoreHandler, PostgresHandler):
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, columns: List = None, **kwargs: Any) -> None:
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
- connection_data = kwargs.get("connection_data", {})
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>")