MindsDB 25.7.4.0__py3-none-any.whl → 25.8.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 (57) hide show
  1. mindsdb/__about__.py +1 -1
  2. mindsdb/__main__.py +11 -1
  3. mindsdb/api/executor/command_executor.py +9 -15
  4. mindsdb/api/executor/sql_query/steps/fetch_dataframe.py +21 -24
  5. mindsdb/api/executor/sql_query/steps/fetch_dataframe_partition.py +9 -3
  6. mindsdb/api/executor/sql_query/steps/subselect_step.py +11 -8
  7. mindsdb/api/executor/utilities/mysql_to_duckdb_functions.py +264 -0
  8. mindsdb/api/executor/utilities/sql.py +30 -0
  9. mindsdb/api/http/initialize.py +2 -1
  10. mindsdb/api/http/namespaces/views.py +56 -72
  11. mindsdb/integrations/handlers/db2_handler/db2_handler.py +19 -23
  12. mindsdb/integrations/handlers/gong_handler/__about__.py +2 -0
  13. mindsdb/integrations/handlers/gong_handler/__init__.py +30 -0
  14. mindsdb/integrations/handlers/gong_handler/connection_args.py +37 -0
  15. mindsdb/integrations/handlers/gong_handler/gong_handler.py +164 -0
  16. mindsdb/integrations/handlers/gong_handler/gong_tables.py +508 -0
  17. mindsdb/integrations/handlers/gong_handler/icon.svg +25 -0
  18. mindsdb/integrations/handlers/gong_handler/test_gong_handler.py +125 -0
  19. mindsdb/integrations/handlers/huggingface_handler/__init__.py +8 -12
  20. mindsdb/integrations/handlers/huggingface_handler/finetune.py +203 -223
  21. mindsdb/integrations/handlers/huggingface_handler/huggingface_handler.py +360 -383
  22. mindsdb/integrations/handlers/huggingface_handler/requirements.txt +7 -7
  23. mindsdb/integrations/handlers/huggingface_handler/requirements_cpu.txt +7 -7
  24. mindsdb/integrations/handlers/huggingface_handler/settings.py +25 -25
  25. mindsdb/integrations/handlers/langchain_handler/langchain_handler.py +1 -2
  26. mindsdb/integrations/handlers/openai_handler/constants.py +11 -30
  27. mindsdb/integrations/handlers/openai_handler/helpers.py +27 -34
  28. mindsdb/integrations/handlers/openai_handler/openai_handler.py +14 -12
  29. mindsdb/integrations/handlers/salesforce_handler/constants.py +9 -2
  30. mindsdb/integrations/libs/llm/config.py +0 -14
  31. mindsdb/integrations/libs/llm/utils.py +0 -15
  32. mindsdb/integrations/utilities/files/file_reader.py +5 -19
  33. mindsdb/integrations/utilities/rag/rerankers/base_reranker.py +1 -1
  34. mindsdb/interfaces/agents/agents_controller.py +83 -45
  35. mindsdb/interfaces/agents/constants.py +0 -1
  36. mindsdb/interfaces/agents/langchain_agent.py +1 -3
  37. mindsdb/interfaces/database/projects.py +111 -7
  38. mindsdb/interfaces/knowledge_base/controller.py +7 -1
  39. mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +6 -10
  40. mindsdb/interfaces/knowledge_base/preprocessing/text_splitter.py +73 -0
  41. mindsdb/interfaces/query_context/context_controller.py +14 -15
  42. mindsdb/utilities/config.py +2 -0
  43. mindsdb/utilities/fs.py +54 -17
  44. {mindsdb-25.7.4.0.dist-info → mindsdb-25.8.2.0.dist-info}/METADATA +278 -263
  45. {mindsdb-25.7.4.0.dist-info → mindsdb-25.8.2.0.dist-info}/RECORD +49 -48
  46. mindsdb/integrations/handlers/anyscale_endpoints_handler/__about__.py +0 -9
  47. mindsdb/integrations/handlers/anyscale_endpoints_handler/__init__.py +0 -20
  48. mindsdb/integrations/handlers/anyscale_endpoints_handler/anyscale_endpoints_handler.py +0 -290
  49. mindsdb/integrations/handlers/anyscale_endpoints_handler/creation_args.py +0 -14
  50. mindsdb/integrations/handlers/anyscale_endpoints_handler/icon.svg +0 -4
  51. mindsdb/integrations/handlers/anyscale_endpoints_handler/requirements.txt +0 -2
  52. mindsdb/integrations/handlers/anyscale_endpoints_handler/settings.py +0 -51
  53. mindsdb/integrations/handlers/anyscale_endpoints_handler/tests/test_anyscale_endpoints_handler.py +0 -212
  54. /mindsdb/integrations/handlers/{anyscale_endpoints_handler/tests/__init__.py → gong_handler/requirements.txt} +0 -0
  55. {mindsdb-25.7.4.0.dist-info → mindsdb-25.8.2.0.dist-info}/WHEEL +0 -0
  56. {mindsdb-25.7.4.0.dist-info → mindsdb-25.8.2.0.dist-info}/licenses/LICENSE +0 -0
  57. {mindsdb-25.7.4.0.dist-info → mindsdb-25.8.2.0.dist-info}/top_level.txt +0 -0
@@ -10,143 +10,127 @@ from mindsdb.metrics.metrics import api_endpoint_metrics
10
10
  from mindsdb.utilities.exception import EntityNotExistsError
11
11
 
12
12
 
13
- @ns_conf.route('/<project_name>/views')
13
+ @ns_conf.route("/<project_name>/views")
14
14
  class ViewsList(Resource):
15
- @ns_conf.doc('list_views')
16
- @api_endpoint_metrics('GET', '/views')
15
+ @ns_conf.doc("list_views")
16
+ @api_endpoint_metrics("GET", "/views")
17
17
  def get(self, project_name):
18
- '''List all views'''
18
+ """List all views"""
19
19
  session = SessionController()
20
20
  try:
21
21
  project = session.database_controller.get_project(project_name)
22
22
  except EntityNotExistsError:
23
- return http_error(
24
- HTTPStatus.NOT_FOUND,
25
- 'Project not found',
26
- f'Project name {project_name} does not exist'
27
- )
23
+ return http_error(HTTPStatus.NOT_FOUND, "Project not found", f"Project name {project_name} does not exist")
28
24
 
29
25
  all_views = project.get_views()
30
26
  all_view_objs = []
31
27
  # Only want to return relevant fields to the user.
32
28
  for view in all_views:
33
- all_view_objs.append({
34
- 'id': view['metadata']['id'],
35
- 'name': view['name'],
36
- 'query': view['query']
37
- })
29
+ all_view_objs.append({"id": view["metadata"]["id"], "name": view["name"], "query": view["query"]})
38
30
  return all_view_objs
39
31
 
40
- @ns_conf.doc('create_view')
41
- @api_endpoint_metrics('POST', '/views')
32
+ @ns_conf.doc("create_view")
33
+ @api_endpoint_metrics("POST", "/views")
42
34
  def post(self, project_name):
43
- '''Create a new view'''
44
- if 'view' not in request.json:
45
- return http_error(HTTPStatus.BAD_REQUEST, 'Wrong argument', 'Must provide "view" parameter in POST body')
35
+ """Create a new view"""
36
+ if "view" not in request.json:
37
+ return http_error(HTTPStatus.BAD_REQUEST, "Wrong argument", 'Must provide "view" parameter in POST body')
46
38
  session = SessionController()
47
- view_obj = request.json['view']
48
- if 'name' not in view_obj:
49
- return http_error(HTTPStatus.BAD_REQUEST, 'Wrong argument', 'Missing "name" field for view')
50
- if 'query' not in view_obj:
51
- return http_error(HTTPStatus.BAD_REQUEST, 'Wrong argument', 'Missing "query" field for view')
52
- name = view_obj['name']
53
- query = view_obj['query']
39
+ view_obj = request.json["view"]
40
+ if "name" not in view_obj:
41
+ return http_error(HTTPStatus.BAD_REQUEST, "Wrong argument", 'Missing "name" field for view')
42
+ if "query" not in view_obj:
43
+ return http_error(HTTPStatus.BAD_REQUEST, "Wrong argument", 'Missing "query" field for view')
44
+ name = view_obj["name"]
45
+ query = view_obj["query"]
54
46
 
55
47
  try:
56
48
  project = session.database_controller.get_project(project_name)
57
49
  except EntityNotExistsError:
58
- return http_error(HTTPStatus.NOT_FOUND, 'Not found', f'Project name {project_name} does not exist')
50
+ return http_error(HTTPStatus.NOT_FOUND, "Not found", f"Project name {project_name} does not exist")
59
51
 
60
52
  if project.get_view(name) is not None:
61
- return http_error(HTTPStatus.CONFLICT, 'Name conflict', f'View with name {name} already exists.')
53
+ return http_error(HTTPStatus.CONFLICT, "Name conflict", f"View with name {name} already exists.")
62
54
 
63
- project.create_view(name, query)
55
+ project.create_view(name, query, session)
64
56
  created_view = project.get_view(name)
65
57
  # Only want to return relevant fields to the user.
66
58
  return {
67
- 'id': created_view['metadata']['id'],
68
- 'name': created_view['name'],
69
- 'query': created_view['query']
59
+ "id": created_view["metadata"]["id"],
60
+ "name": created_view["name"],
61
+ "query": created_view["query"],
70
62
  }, HTTPStatus.CREATED
71
63
 
72
64
 
73
- @ns_conf.route('/<project_name>/views/<view_name>')
74
- @ns_conf.param('project_name', 'Name of the project')
75
- @ns_conf.param('view_name', 'Name of the view')
65
+ @ns_conf.route("/<project_name>/views/<view_name>")
66
+ @ns_conf.param("project_name", "Name of the project")
67
+ @ns_conf.param("view_name", "Name of the view")
76
68
  class ViewResource(Resource):
77
- @ns_conf.doc('get_view')
78
- @api_endpoint_metrics('GET', '/views/view')
69
+ @ns_conf.doc("get_view")
70
+ @api_endpoint_metrics("GET", "/views/view")
79
71
  def get(self, project_name, view_name):
80
- '''Get a view by name'''
72
+ """Get a view by name"""
81
73
  session = SessionController()
82
74
  try:
83
75
  project = session.database_controller.get_project(project_name)
84
76
  except EntityNotExistsError:
85
- return http_error(HTTPStatus.NOT_FOUND, 'Project not found', f'Project name {project_name} does not exist')
77
+ return http_error(HTTPStatus.NOT_FOUND, "Project not found", f"Project name {project_name} does not exist")
86
78
 
87
79
  view = project.get_view(view_name)
88
80
  if view is None:
89
- return http_error(HTTPStatus.NOT_FOUND, 'View not found', f'View with name {view_name} does not exist')
81
+ return http_error(HTTPStatus.NOT_FOUND, "View not found", f"View with name {view_name} does not exist")
90
82
 
91
83
  # Only want to return relevant fields to the user.
92
- return {
93
- 'id': view['metadata']['id'],
94
- 'name': view['name'],
95
- 'query': view['query']
96
- }
84
+ return {"id": view["metadata"]["id"], "name": view["name"], "query": view["query"]}
97
85
 
98
- @ns_conf.doc('update_view')
99
- @api_endpoint_metrics('PUT', '/views/view')
86
+ @ns_conf.doc("update_view")
87
+ @api_endpoint_metrics("PUT", "/views/view")
100
88
  def put(self, project_name, view_name):
101
- '''Updates or creates a view'''
102
- if 'view' not in request.json:
103
- return http_error(HTTPStatus.BAD_REQUEST, 'Wrong argument', 'Must provide "view" parameter in PUT body')
104
- request_view = request.json['view']
89
+ """Updates or creates a view"""
90
+ if "view" not in request.json:
91
+ return http_error(HTTPStatus.BAD_REQUEST, "Wrong argument", 'Must provide "view" parameter in PUT body')
92
+ request_view = request.json["view"]
105
93
  session = SessionController()
106
94
  try:
107
95
  project = session.database_controller.get_project(project_name)
108
96
  except EntityNotExistsError:
109
- return http_error(HTTPStatus.NOT_FOUND, 'Project not found', f'Project name {project_name} does not exist')
97
+ return http_error(HTTPStatus.NOT_FOUND, "Project not found", f"Project name {project_name} does not exist")
110
98
 
111
99
  existing_view = project.get_view(view_name)
112
100
  if existing_view is None:
113
101
  # Create
114
- if 'query' not in request_view:
115
- return http_error(HTTPStatus.BAD_REQUEST, 'Wrong argument', 'Missing "query" field for new view')
116
- project.create_view(view_name, request_view['query'])
102
+ if "query" not in request_view:
103
+ return http_error(HTTPStatus.BAD_REQUEST, "Wrong argument", 'Missing "query" field for new view')
104
+ project.create_view(view_name, request_view["query"], session)
117
105
  created_view = project.get_view(view_name)
118
106
  # Only want to return relevant fields to the user.
119
107
  return {
120
- 'id': created_view['metadata']['id'],
121
- 'name': created_view['name'],
122
- 'query': created_view['query']
108
+ "id": created_view["metadata"]["id"],
109
+ "name": created_view["name"],
110
+ "query": created_view["query"],
123
111
  }, HTTPStatus.CREATED
124
112
 
125
- new_query = existing_view['query']
126
- if 'query' in request_view:
127
- new_query = request_view['query']
113
+ new_query = existing_view["query"]
114
+ if "query" in request_view:
115
+ new_query = request_view["query"]
128
116
  project.update_view(view_name, new_query)
129
117
 
130
118
  existing_view = project.get_view(view_name)
131
119
  # Only want to return relevant fields to the user.
132
- return {
133
- 'id': existing_view['metadata']['id'],
134
- 'name': existing_view['name'],
135
- 'query': existing_view['query']
136
- }
120
+ return {"id": existing_view["metadata"]["id"], "name": existing_view["name"], "query": existing_view["query"]}
137
121
 
138
- @ns_conf.doc('delete_view')
139
- @api_endpoint_metrics('DELETE', '/views/view')
122
+ @ns_conf.doc("delete_view")
123
+ @api_endpoint_metrics("DELETE", "/views/view")
140
124
  def delete(self, project_name, view_name):
141
- '''Deletes a view by name'''
125
+ """Deletes a view by name"""
142
126
  session = SessionController()
143
127
  try:
144
128
  project = session.database_controller.get_project(project_name)
145
129
  except EntityNotExistsError:
146
- return http_error(HTTPStatus.NOT_FOUND, 'Project not found', f'Project name {project_name} does not exist')
130
+ return http_error(HTTPStatus.NOT_FOUND, "Project not found", f"Project name {project_name} does not exist")
147
131
 
148
132
  if project.get_view(view_name) is None:
149
- return http_error(HTTPStatus.NOT_FOUND, 'View not found', f'View with name {view_name} does not exist')
133
+ return http_error(HTTPStatus.NOT_FOUND, "View not found", f"View with name {view_name} does not exist")
150
134
 
151
135
  project.delete_view(view_name)
152
- return '', HTTPStatus.NO_CONTENT
136
+ return "", HTTPStatus.NO_CONTENT
@@ -59,16 +59,20 @@ class DB2Handler(DatabaseHandler):
59
59
  return self.connection
60
60
 
61
61
  # Mandatory connection parameters.
62
- if not all(key in self.connection_data for key in ['host', 'user', 'password', 'database']):
63
- raise ValueError('Required parameters (host, user, password, database) must be provided.')
64
-
65
- connection_string = f"DRIVER={'IBM DB2 ODBC DRIVER'};DATABASE={self.connection_data['database']};HOST={self.connection_data['host']};PROTOCOL=TCPIP;UID={self.connection_data['user']};PWD={self.connection_data['password']};"
66
-
67
- # Optional connection parameters.
68
- if 'port' in self.connection_data:
69
- connection_string += f"PORT={self.connection_data['port']};"
70
-
71
- if 'schema' in self.connection_data:
62
+ if not all(key in self.connection_data for key in ["host", "user", "password", "database"]):
63
+ raise ValueError("Required parameters (host, user, password, database) must be provided.")
64
+ cloud = "databases.appdomain.cloud" in self.connection_data["host"]
65
+ if cloud:
66
+ connection_string = f"DATABASE={self.connection_data['database']};HOSTNAME={self.connection_data['host']};PORT={self.connection_data['port']};PROTOCOL=TCPIP;UID={self.connection_data['user']};PWD={self.connection_data['password']};SECURITY=SSL;"
67
+ connection_string += "SSLSERVERCERTIFICATE=;"
68
+ else:
69
+ connection_string = f"DRIVER={'IBM DB2 ODBC DRIVER'};DATABASE={self.connection_data['database']};HOST={self.connection_data['host']};PROTOCOL=TCPIP;UID={self.connection_data['user']};PWD={self.connection_data['password']};"
70
+
71
+ # Optional connection parameters.
72
+ if "port" in self.connection_data:
73
+ connection_string += f"PORT={self.connection_data['port']};"
74
+
75
+ if "schema" in self.connection_data:
72
76
  connection_string += f"CURRENTSCHEMA={self.connection_data['schema']};"
73
77
 
74
78
  try:
@@ -106,10 +110,10 @@ class DB2Handler(DatabaseHandler):
106
110
  self.connect()
107
111
  response.success = True
108
112
  except (OperationalError, ValueError) as known_error:
109
- logger.error(f'Connection check to IBM Db2 failed, {known_error}!')
113
+ logger.error(f"Connection check to IBM Db2 failed, {known_error}!")
110
114
  response.error_message = str(known_error)
111
115
  except Exception as unknown_error:
112
- logger.error(f'Connection check to IBM Db2 failed due to an unknown error, {unknown_error}!')
116
+ logger.error(f"Connection check to IBM Db2 failed due to an unknown error, {unknown_error}!")
113
117
  response.error_message = str(unknown_error)
114
118
 
115
119
  if response.success and need_to_close:
@@ -141,9 +145,7 @@ class DB2Handler(DatabaseHandler):
141
145
  result = cur.fetchall()
142
146
  response = Response(
143
147
  RESPONSE_TYPE.TABLE,
144
- data_frame=pd.DataFrame(
145
- result, columns=[x[0] for x in cur.description]
146
- ),
148
+ data_frame=pd.DataFrame(result, columns=[x[0] for x in cur.description]),
147
149
  )
148
150
  else:
149
151
  response = Response(RESPONSE_TYPE.OK)
@@ -198,10 +200,7 @@ class DB2Handler(DatabaseHandler):
198
200
  }
199
201
  )
200
202
 
201
- response = Response(
202
- RESPONSE_TYPE.TABLE,
203
- data_frame=pd.DataFrame(tables)
204
- )
203
+ response = Response(RESPONSE_TYPE.TABLE, data_frame=pd.DataFrame(tables))
205
204
 
206
205
  return response
207
206
 
@@ -227,9 +226,6 @@ class DB2Handler(DatabaseHandler):
227
226
 
228
227
  columns = [column["COLUMN_NAME"] for column in result]
229
228
 
230
- response = Response(
231
- RESPONSE_TYPE.TABLE,
232
- data_frame=pd.DataFrame(columns, columns=["COLUMN_NAME"])
233
- )
229
+ response = Response(RESPONSE_TYPE.TABLE, data_frame=pd.DataFrame(columns, columns=["COLUMN_NAME"]))
234
230
 
235
231
  return response
@@ -0,0 +1,2 @@
1
+ __version__ = "0.0.1"
2
+ __description__ = "Gong conversation intelligence platform handler for MindsDB"
@@ -0,0 +1,30 @@
1
+ from mindsdb.integrations.libs.const import HANDLER_TYPE
2
+
3
+ from .__about__ import __version__ as version, __description__ as description
4
+ from .connection_args import connection_args, connection_args_example
5
+
6
+ try:
7
+ from .gong_handler import GongHandler as Handler
8
+
9
+ import_error = None
10
+ except Exception as e:
11
+ Handler = None
12
+ import_error = e
13
+
14
+ title = "Gong"
15
+ name = "gong"
16
+ type = HANDLER_TYPE.DATA
17
+ icon_path = "icon.svg"
18
+
19
+ __all__ = [
20
+ "Handler",
21
+ "version",
22
+ "name",
23
+ "type",
24
+ "title",
25
+ "description",
26
+ "import_error",
27
+ "icon_path",
28
+ "connection_args_example",
29
+ "connection_args",
30
+ ]
@@ -0,0 +1,37 @@
1
+ from collections import OrderedDict
2
+
3
+ from mindsdb.integrations.libs.const import HANDLER_CONNECTION_ARG_TYPE as ARG_TYPE
4
+
5
+
6
+ connection_args = OrderedDict(
7
+ api_key={
8
+ "type": ARG_TYPE.PWD,
9
+ "description": "Gong API key for authentication.",
10
+ "secret": True,
11
+ "required": False,
12
+ "label": "API Key",
13
+ },
14
+ # Basic Authentication with Access Key + Secret Key (Option 2)
15
+ access_key={
16
+ "type": ARG_TYPE.STR,
17
+ "description": "Gong Access Key for basic authentication (if not using OAuth).",
18
+ "secret": True,
19
+ "required": False,
20
+ "label": "Access Key",
21
+ },
22
+ secret_key={
23
+ "type": ARG_TYPE.PWD,
24
+ "description": "Gong Secret Key for basic authentication (if not using OAuth).",
25
+ "secret": True,
26
+ "required": False,
27
+ "label": "Secret Key",
28
+ },
29
+ base_url={
30
+ "type": ARG_TYPE.STR,
31
+ "description": "Gong API base URL (optional, defaults to production).",
32
+ "required": False,
33
+ "label": "Base URL",
34
+ },
35
+ )
36
+
37
+ connection_args_example = OrderedDict(api_key="your_gong_api_key_here", base_url="https://api.gong.io")
@@ -0,0 +1,164 @@
1
+ import requests
2
+ from typing import Any, Dict
3
+
4
+ from mindsdb_sql_parser import parse_sql
5
+
6
+ from mindsdb.integrations.handlers.gong_handler.gong_tables import (
7
+ GongCallsTable,
8
+ GongUsersTable,
9
+ GongAnalyticsTable,
10
+ GongTranscriptsTable,
11
+ )
12
+ from mindsdb.integrations.libs.api_handler import APIHandler
13
+ from mindsdb.integrations.libs.response import (
14
+ HandlerResponse as Response,
15
+ HandlerStatusResponse as StatusResponse,
16
+ RESPONSE_TYPE,
17
+ )
18
+ from mindsdb.utilities import log
19
+
20
+
21
+ logger = log.getLogger(__name__)
22
+
23
+
24
+ class GongHandler(APIHandler):
25
+ """
26
+ This handler handles the connection and execution of SQL statements on Gong.
27
+ """
28
+
29
+ name = "gong"
30
+
31
+ def __init__(self, name: str, connection_data: Dict, **kwargs: Any) -> None:
32
+ """
33
+ Initializes the handler.
34
+
35
+ Args:
36
+ name (Text): The name of the handler instance.
37
+ connection_data (Dict): The connection data required to connect to the Gong API.
38
+ kwargs: Arbitrary keyword arguments.
39
+ """
40
+ super().__init__(name)
41
+ self.connection_data = connection_data
42
+ self.kwargs = kwargs
43
+
44
+ self.connection = None
45
+ self.is_connected = False
46
+ self.base_url = connection_data.get("base_url", "https://api.gong.io")
47
+
48
+ # Support both bearer token and access key + secret key
49
+ self.bearer_token = connection_data.get("api_key")
50
+ self.access_key = connection_data.get("access_key")
51
+ self.secret_key = connection_data.get("secret_key")
52
+
53
+ # Register core tables
54
+ self._register_table("calls", GongCallsTable(self))
55
+ self._register_table("users", GongUsersTable(self))
56
+ self._register_table("analytics", GongAnalyticsTable(self))
57
+ self._register_table("transcripts", GongTranscriptsTable(self))
58
+
59
+ def connect(self) -> requests.Session:
60
+ """
61
+ Establishes a connection to the Gong API.
62
+
63
+ Raises:
64
+ ValueError: If the required connection parameters are not provided.
65
+ Exception: If a connection error occurs.
66
+
67
+ Returns:
68
+ requests.Session: A session object for making API requests.
69
+ """
70
+ if self.is_connected is True:
71
+ return self.connection
72
+
73
+ if self.access_key and self.secret_key:
74
+ auth_method = "basic"
75
+ elif self.bearer_token:
76
+ auth_method = "bearer"
77
+ else:
78
+ raise ValueError("Either bearer_token or (access_key + secret_key) is required to connect to Gong API.")
79
+
80
+ try:
81
+ self.connection = requests.Session()
82
+
83
+ if auth_method == "basic":
84
+ # Basic authentication with access key + secret key
85
+ self.connection.auth = (self.access_key, self.secret_key)
86
+ self.connection.headers.update({"Content-Type": "application/json", "Accept": "application/json"})
87
+ else:
88
+ # Bearer token authentication
89
+ self.connection.headers.update(
90
+ {
91
+ "Authorization": f"Bearer {self.bearer_token}",
92
+ "Content-Type": "application/json",
93
+ "Accept": "application/json",
94
+ }
95
+ )
96
+
97
+ test_response = self.connection.get(f"{self.base_url}/v2/users")
98
+ test_response.raise_for_status()
99
+
100
+ self.is_connected = True
101
+ return self.connection
102
+
103
+ except Exception as e:
104
+ self.is_connected = False
105
+ logger.error(f"Error connecting to Gong API: {e}")
106
+ raise
107
+
108
+ def check_connection(self) -> StatusResponse:
109
+ """
110
+ Checks the status of the connection to the Gong API.
111
+
112
+ Returns:
113
+ StatusResponse: An object containing the success status and an error message if an error occurs.
114
+ """
115
+ response = StatusResponse(False)
116
+
117
+ try:
118
+ self.connect()
119
+ # Test the connection by making a simple API call
120
+ test_response = self.connection.get(f"{self.base_url}/v2/users")
121
+ test_response.raise_for_status()
122
+ response.success = True
123
+ except Exception as e:
124
+ logger.error(f"Connection check to Gong failed: {e}")
125
+ response.error_message = str(e)
126
+
127
+ self.is_connected = response.success
128
+ return response
129
+
130
+ def native_query(self, query: str) -> Response:
131
+ """
132
+ Executes a native query on Gong and returns the result.
133
+
134
+ Args:
135
+ query (Text): The SQL query to be executed.
136
+
137
+ Returns:
138
+ Response: A response object containing the result of the query or an error message.
139
+ """
140
+ try:
141
+ ast = parse_sql(query)
142
+ return self.query(ast)
143
+ except Exception as e:
144
+ logger.error(f"Error running query: {query} on Gong: {e}")
145
+ return Response(RESPONSE_TYPE.ERROR, error_code=0, error_message=str(e))
146
+
147
+ def call_gong_api(self, endpoint: str, params: Dict = None) -> Dict:
148
+ """
149
+ Makes a call to the Gong API.
150
+
151
+ Args:
152
+ endpoint (str): The API endpoint to call.
153
+ params (Dict): Query parameters for the API call.
154
+
155
+ Returns:
156
+ Dict: The API response.
157
+ """
158
+ if not self.is_connected:
159
+ self.connect()
160
+
161
+ url = f"{self.base_url}{endpoint}"
162
+ response = self.connection.get(url, params=params)
163
+ response.raise_for_status()
164
+ return response.json()