MindsDB 25.4.4.0__py3-none-any.whl → 25.5.3.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 (86) hide show
  1. mindsdb/__about__.py +1 -1
  2. mindsdb/__main__.py +107 -125
  3. mindsdb/api/executor/command_executor.py +14 -3
  4. mindsdb/api/executor/datahub/datanodes/information_schema_datanode.py +8 -0
  5. mindsdb/api/executor/datahub/datanodes/mindsdb_tables.py +2 -1
  6. mindsdb/api/executor/datahub/datanodes/system_tables.py +10 -13
  7. mindsdb/api/executor/planner/query_plan.py +1 -0
  8. mindsdb/api/executor/planner/query_planner.py +9 -1
  9. mindsdb/api/executor/sql_query/sql_query.py +24 -8
  10. mindsdb/api/executor/sql_query/steps/apply_predictor_step.py +21 -3
  11. mindsdb/api/executor/sql_query/steps/fetch_dataframe_partition.py +3 -1
  12. mindsdb/api/http/initialize.py +20 -3
  13. mindsdb/api/http/namespaces/analysis.py +14 -1
  14. mindsdb/api/http/namespaces/config.py +19 -11
  15. mindsdb/api/http/namespaces/tree.py +1 -1
  16. mindsdb/api/http/start.py +7 -2
  17. mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +4 -8
  18. mindsdb/api/mysql/mysql_proxy/utilities/exceptions.py +0 -4
  19. mindsdb/api/postgres/postgres_proxy/postgres_packets/postgres_message_formats.py +2 -2
  20. mindsdb/integrations/handlers/bigquery_handler/requirements.txt +1 -0
  21. mindsdb/integrations/handlers/chromadb_handler/requirements.txt +1 -0
  22. mindsdb/integrations/handlers/gmail_handler/requirements.txt +1 -0
  23. mindsdb/integrations/handlers/google_analytics_handler/requirements.txt +2 -1
  24. mindsdb/integrations/handlers/google_books_handler/requirements.txt +1 -1
  25. mindsdb/integrations/handlers/google_calendar_handler/requirements.txt +1 -0
  26. mindsdb/integrations/handlers/google_content_shopping_handler/requirements.txt +1 -1
  27. mindsdb/integrations/handlers/google_fit_handler/requirements.txt +2 -0
  28. mindsdb/integrations/handlers/google_search_handler/requirements.txt +1 -1
  29. mindsdb/integrations/handlers/jira_handler/jira_handler.archived.py +75 -0
  30. mindsdb/integrations/handlers/jira_handler/jira_handler.py +113 -38
  31. mindsdb/integrations/handlers/jira_handler/jira_tables.py +229 -0
  32. mindsdb/integrations/handlers/jira_handler/requirements.txt +1 -0
  33. mindsdb/integrations/handlers/lightfm_handler/requirements.txt +1 -0
  34. mindsdb/integrations/handlers/lightwood_handler/lightwood_handler.py +0 -2
  35. mindsdb/integrations/handlers/lightwood_handler/requirements.txt +4 -4
  36. mindsdb/integrations/handlers/lindorm_handler/requirements.txt +1 -0
  37. mindsdb/integrations/handlers/ms_one_drive_handler/requirements.txt +2 -0
  38. mindsdb/integrations/handlers/ms_teams_handler/requirements.txt +3 -1
  39. mindsdb/integrations/handlers/openai_handler/helpers.py +3 -5
  40. mindsdb/integrations/handlers/openai_handler/openai_handler.py +25 -12
  41. mindsdb/integrations/handlers/snowflake_handler/requirements.txt +1 -1
  42. mindsdb/integrations/handlers/togetherai_handler/__about__.py +9 -0
  43. mindsdb/integrations/handlers/togetherai_handler/__init__.py +20 -0
  44. mindsdb/integrations/handlers/togetherai_handler/creation_args.py +14 -0
  45. mindsdb/integrations/handlers/togetherai_handler/icon.svg +15 -0
  46. mindsdb/integrations/handlers/togetherai_handler/model_using_args.py +5 -0
  47. mindsdb/integrations/handlers/togetherai_handler/requirements.txt +2 -0
  48. mindsdb/integrations/handlers/togetherai_handler/settings.py +33 -0
  49. mindsdb/integrations/handlers/togetherai_handler/togetherai_handler.py +234 -0
  50. mindsdb/integrations/handlers/vertex_handler/requirements.txt +1 -0
  51. mindsdb/integrations/handlers/youtube_handler/requirements.txt +1 -0
  52. mindsdb/integrations/utilities/files/file_reader.py +5 -2
  53. mindsdb/integrations/utilities/handler_utils.py +4 -0
  54. mindsdb/integrations/utilities/rag/rerankers/base_reranker.py +360 -0
  55. mindsdb/integrations/utilities/rag/rerankers/reranker_compressor.py +6 -346
  56. mindsdb/interfaces/agents/constants.py +14 -2
  57. mindsdb/interfaces/agents/langchain_agent.py +2 -4
  58. mindsdb/interfaces/database/projects.py +1 -7
  59. mindsdb/interfaces/functions/controller.py +14 -16
  60. mindsdb/interfaces/functions/to_markdown.py +9 -124
  61. mindsdb/interfaces/knowledge_base/controller.py +109 -92
  62. mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +28 -5
  63. mindsdb/interfaces/knowledge_base/utils.py +10 -15
  64. mindsdb/interfaces/model/model_controller.py +0 -2
  65. mindsdb/interfaces/query_context/context_controller.py +55 -15
  66. mindsdb/interfaces/query_context/query_task.py +19 -0
  67. mindsdb/interfaces/skills/sql_agent.py +33 -11
  68. mindsdb/interfaces/storage/db.py +2 -2
  69. mindsdb/interfaces/tasks/task_monitor.py +5 -1
  70. mindsdb/interfaces/tasks/task_thread.py +6 -0
  71. mindsdb/migrations/migrate.py +0 -2
  72. mindsdb/migrations/versions/2025-04-22_53502b6d63bf_query_database.py +27 -0
  73. mindsdb/utilities/config.py +15 -3
  74. mindsdb/utilities/context.py +2 -1
  75. mindsdb/utilities/functions.py +0 -36
  76. mindsdb/utilities/langfuse.py +19 -10
  77. mindsdb/utilities/otel/__init__.py +9 -193
  78. mindsdb/utilities/otel/metric_handlers/__init__.py +5 -1
  79. mindsdb/utilities/otel/prepare.py +198 -0
  80. mindsdb/utilities/sql.py +83 -0
  81. {mindsdb-25.4.4.0.dist-info → mindsdb-25.5.3.0.dist-info}/METADATA +662 -592
  82. {mindsdb-25.4.4.0.dist-info → mindsdb-25.5.3.0.dist-info}/RECORD +85 -69
  83. {mindsdb-25.4.4.0.dist-info → mindsdb-25.5.3.0.dist-info}/WHEEL +1 -1
  84. mindsdb/api/mysql/mysql_proxy/classes/sql_statement_parser.py +0 -151
  85. {mindsdb-25.4.4.0.dist-info → mindsdb-25.5.3.0.dist-info}/licenses/LICENSE +0 -0
  86. {mindsdb-25.4.4.0.dist-info → mindsdb-25.5.3.0.dist-info}/top_level.txt +0 -0
@@ -27,33 +27,41 @@ class GetConfig(Resource):
27
27
  @api_endpoint_metrics('GET', '/config')
28
28
  def get(self):
29
29
  config = Config()
30
- return {
30
+ resp = {
31
31
  'auth': {
32
32
  'http_auth_enabled': config['auth']['http_auth_enabled']
33
33
  }
34
34
  }
35
+ for key in ['default_llm', 'default_embedding_model']:
36
+ value = config.get(key)
37
+ if value is not None:
38
+ resp[key] = value
39
+ return resp
35
40
 
36
41
  @ns_conf.doc('put_config')
37
42
  @api_endpoint_metrics('PUT', '/config')
38
43
  def put(self):
39
44
  data = request.json
40
45
 
41
- unknown_argumens = list(set(data.keys()) - {'auth'})
42
- if len(unknown_argumens) > 0:
46
+ allowed_arguments = {'auth', 'default_llm', 'default_embedding_model'}
47
+ unknown_arguments = list(set(data.keys()) - allowed_arguments)
48
+ if len(unknown_arguments) > 0:
43
49
  return http_error(
44
50
  HTTPStatus.BAD_REQUEST, 'Wrong arguments',
45
- f'Unknown argumens: {unknown_argumens}'
51
+ f'Unknown argumens: {unknown_arguments}'
46
52
  )
47
53
 
54
+ nested_keys_to_validate = {'auth'}
48
55
  for key in data.keys():
49
- unknown_argumens = list(
50
- set(data[key].keys()) - set(Config()[key].keys())
51
- )
52
- if len(unknown_argumens) > 0:
53
- return http_error(
54
- HTTPStatus.BAD_REQUEST, 'Wrong arguments',
55
- f'Unknown argumens: {unknown_argumens}'
56
+ if key in nested_keys_to_validate:
57
+ unknown_arguments = list(
58
+ set(data[key].keys()) - set(Config()[key].keys())
56
59
  )
60
+ if len(unknown_arguments) > 0:
61
+ return http_error(
62
+ HTTPStatus.BAD_REQUEST, 'Wrong arguments',
63
+ f'Unknown argumens: {unknown_arguments}'
64
+ )
57
65
 
58
66
  Config().update(data)
59
67
 
@@ -94,7 +94,7 @@ class GetLeaf(Resource):
94
94
  } for key, val in schemas.items()]
95
95
  elif db['type'] == 'system':
96
96
  system_db = ca.database_controller.get_system_db(db_name)
97
- tables = system_db.get_tables()
97
+ tables = system_db.get_tree_tables()
98
98
  tables = [{
99
99
  'name': table.name,
100
100
  'class': table.kind,
mindsdb/api/http/start.py CHANGED
@@ -1,3 +1,6 @@
1
+ import gc
2
+ gc.disable()
3
+
1
4
  from flask import Flask
2
5
  from waitress import serve
3
6
 
@@ -8,6 +11,8 @@ from mindsdb.utilities.config import config
8
11
  from mindsdb.utilities.functions import init_lexer_parsers
9
12
  from mindsdb.integrations.libs.ml_exec_base import process_cache
10
13
 
14
+ gc.enable()
15
+
11
16
  logger = log.getLogger(__name__)
12
17
 
13
18
 
@@ -26,7 +31,7 @@ def start(verbose, no_studio, app: Flask = None):
26
31
  process_cache.init()
27
32
 
28
33
  if server_type == "waitress":
29
- logger.debug("Serving HTTP app with waitress..")
34
+ logger.debug("Serving HTTP app with waitress...")
30
35
  serve(
31
36
  app,
32
37
  host='*' if host in ('', '0.0.0.0') else host,
@@ -34,7 +39,7 @@ def start(verbose, no_studio, app: Flask = None):
34
39
  **server_config
35
40
  )
36
41
  elif server_type == "flask":
37
- logger.debug("Serving HTTP app with flask..")
42
+ logger.debug("Serving HTTP app with flask...")
38
43
  # that will 'disable access' log in console
39
44
 
40
45
  app.run(debug=False, port=port, host=host, **server_config)
@@ -32,13 +32,11 @@ from mindsdb.api.mysql.mysql_proxy.data_types.mysql_datum import Datum
32
32
 
33
33
  import mindsdb.utilities.hooks as hooks
34
34
  import mindsdb.utilities.profiler as profiler
35
+ from mindsdb.utilities.sql import clear_sql
35
36
  from mindsdb.api.mysql.mysql_proxy.classes.client_capabilities import ClentCapabilities
36
37
  from mindsdb.api.mysql.mysql_proxy.classes.server_capabilities import (
37
38
  server_capabilities,
38
39
  )
39
- from mindsdb.api.mysql.mysql_proxy.classes.sql_statement_parser import (
40
- SqlStatementParser,
41
- )
42
40
  from mindsdb.api.executor.controllers import SessionController
43
41
  from mindsdb.api.mysql.mysql_proxy.data_types.mysql_packet import Packet
44
42
  from mindsdb.api.mysql.mysql_proxy.data_types.mysql_packets import (
@@ -85,7 +83,7 @@ from mindsdb.api.mysql.mysql_proxy.utilities.lightwood_dtype import dtype
85
83
  from mindsdb.utilities import log
86
84
  from mindsdb.utilities.config import config
87
85
  from mindsdb.utilities.context import context as ctx
88
- from mindsdb.utilities.otel.metric_handlers import get_query_request_counter
86
+ from mindsdb.utilities.otel import increment_otel_query_request_counter
89
87
  from mindsdb.utilities.wizards import make_ssl_cert
90
88
 
91
89
  logger = log.getLogger(__name__)
@@ -560,9 +558,7 @@ class MysqlProxy(SocketServer.BaseRequestHandler):
560
558
  )
561
559
 
562
560
  # Increment the counter and include metadata in attributes
563
- metadata = ctx.metadata(query=sql)
564
- query_request_counter = get_query_request_counter()
565
- query_request_counter.add(1, metadata)
561
+ increment_otel_query_request_counter(ctx.get_metadata(query=sql))
566
562
 
567
563
  return resp
568
564
 
@@ -741,7 +737,7 @@ class MysqlProxy(SocketServer.BaseRequestHandler):
741
737
  try:
742
738
  if p.type.value == COMMANDS.COM_QUERY:
743
739
  sql = self.decode_utf(p.sql.value)
744
- sql = SqlStatementParser.clear_sql(sql)
740
+ sql = clear_sql(sql)
745
741
  logger.debug(f'Incoming query: {sql}')
746
742
  profiler.set_meta(
747
743
  query=sql, api="mysql", environment=config.get("environment")
@@ -12,7 +12,3 @@ class ErSqlSyntaxError(SqlApiException):
12
12
 
13
13
  class ErWrongCharset(SqlApiException):
14
14
  err_code = ERR.ER_UNKNOWN_CHARACTER_SET
15
-
16
-
17
- class ErParseError(SqlApiException):
18
- err_code = ERR.ER_PARSE_ERROR
@@ -1,6 +1,5 @@
1
1
  from typing import BinaryIO, Sequence, Dict, Type
2
2
 
3
- from mindsdb.api.mysql.mysql_proxy.classes.sql_statement_parser import SqlStatementParser
4
3
  from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_fields import PostgresField
5
4
  from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_message import PostgresMessage
6
5
  from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_message_identifiers import \
@@ -8,6 +7,7 @@ from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_message_ident
8
7
 
9
8
  from mindsdb.api.postgres.postgres_proxy.postgres_packets.postgres_packets import PostgresPacketReader
10
9
  from mindsdb.api.postgres.postgres_proxy.utilities import strip_null_byte
10
+ from mindsdb.utilities.sql import clear_sql
11
11
 
12
12
 
13
13
  # All docstrings for Messages are taken from
@@ -507,7 +507,7 @@ class Query(PostgresMessage):
507
507
  raise Exception(f'SQL contains non {encoding} values: {self.sql}')
508
508
  # Remove null bytes from end of sql statement. This is important.
509
509
  sql = strip_null_byte(sql)
510
- sql = SqlStatementParser.clear_sql(sql)
510
+ sql = clear_sql(sql)
511
511
  return sql
512
512
 
513
513
 
@@ -1,2 +1,3 @@
1
1
  google-cloud-bigquery[pandas]
2
2
  sqlalchemy-bigquery
3
+ -r mindsdb/integrations/utilities/handlers/auth_utilities/google/requirements.txt
@@ -1 +1,2 @@
1
1
  chromadb~=0.6.3
2
+ onnxruntime==1.20.1 # 1.21.0 (latest as of April 10, 2025) causes issues in Windows
@@ -1 +1,2 @@
1
1
  google-api-python-client
2
+ -r mindsdb/integrations/utilities/handlers/auth_utilities/google/requirements.txt
@@ -1,2 +1,3 @@
1
1
  google-api-python-client
2
- google-analytics-admin
2
+ google-analytics-admin
3
+ google-auth
@@ -1,2 +1,2 @@
1
1
  google-api-python-client
2
- google-auth-httplib2
2
+ google-auth
@@ -1 +1,2 @@
1
1
  google-api-python-client
2
+ -r mindsdb/integrations/utilities/handlers/auth_utilities/google/requirements.txt
@@ -1,2 +1,2 @@
1
1
  google-api-python-client
2
- google-auth-httplib2
2
+ google-auth
@@ -2,3 +2,5 @@ tzlocal
2
2
  google
3
3
  google-api-python-client
4
4
  tzlocal
5
+ google-auth
6
+ google-auth-oauthlib
@@ -1,2 +1,2 @@
1
1
  google-api-python-client
2
- google-auth-httplib2
2
+ google-auth
@@ -0,0 +1,75 @@
1
+ from mindsdb.integrations.libs.api_handler import APIHandler
2
+ from mindsdb.integrations.libs.response import (
3
+ HandlerStatusResponse as StatusResponse,
4
+ )
5
+ from mindsdb.utilities import log
6
+ from mindsdb.integrations.libs.api_handler_generator import APIResourceGenerator
7
+
8
+
9
+ logger = log.getLogger(__name__)
10
+
11
+
12
+ class JiraHandler(APIHandler):
13
+
14
+ def __init__(self, name=None, **kwargs):
15
+ """
16
+ Initialize the handler.
17
+ Args:
18
+ name (str): name of particular handler instance
19
+ connection_data (dict): parameters for connecting to the database
20
+ **kwargs: arbitrary keyword arguments.
21
+ """
22
+ super().__init__(name)
23
+ self.connection_data = kwargs.get("connection_data", {})
24
+
25
+ self.connection = None
26
+ self.is_connected = False
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)
42
+
43
+ for table_name, resource in resource_tables.items():
44
+ self._register_table(table_name, resource)
45
+
46
+ def __del__(self):
47
+ if self.is_connected is True:
48
+ self.disconnect()
49
+
50
+ def connect(self):
51
+ """
52
+ Set up the connection required by the handler.
53
+ Returns:
54
+ HandlerStatusResponse
55
+ """
56
+ return
57
+
58
+ def check_connection(self) -> StatusResponse:
59
+ """
60
+ Check connection to the handler.
61
+ Returns:
62
+ HandlerStatusResponse
63
+ """
64
+
65
+ response = StatusResponse(False)
66
+
67
+ try:
68
+ self.api_resource_generator.check_connection()
69
+ response.success = True
70
+ except Exception as e:
71
+ logger.error(f"Error connecting to Jira API: {e}!")
72
+ response.error_message = e
73
+
74
+ self.is_connected = response.success
75
+ return response
@@ -1,75 +1,150 @@
1
+ from typing import Any, Dict
2
+
3
+ from atlassian import Jira
4
+ from requests.exceptions import HTTPError
5
+
6
+ from mindsdb.integrations.handlers.jira_handler.jira_tables import JiraProjectsTable, JiraIssuesTable, JiraUsersTable, JiraGroupsTable
1
7
  from mindsdb.integrations.libs.api_handler import APIHandler
2
8
  from mindsdb.integrations.libs.response import (
9
+ HandlerResponse as Response,
3
10
  HandlerStatusResponse as StatusResponse,
11
+ RESPONSE_TYPE,
4
12
  )
5
13
  from mindsdb.utilities import log
6
- from mindsdb.integrations.libs.api_handler_generator import APIResourceGenerator
7
14
 
8
15
 
9
16
  logger = log.getLogger(__name__)
10
17
 
11
18
 
12
19
  class JiraHandler(APIHandler):
20
+ """
21
+ This handler handles the connection and execution of SQL statements on Jira.
22
+ """
13
23
 
14
- def __init__(self, name=None, **kwargs):
24
+ def __init__(self, name: str, connection_data: Dict, **kwargs: Any) -> None:
15
25
  """
16
- Initialize the handler.
26
+ Initializes the handler.
27
+
17
28
  Args:
18
- name (str): name of particular handler instance
19
- connection_data (dict): parameters for connecting to the database
20
- **kwargs: arbitrary keyword arguments.
29
+ name (Text): The name of the handler instance.
30
+ connection_data (Dict): The connection data required to connect to the Jira API.
31
+ kwargs: Arbitrary keyword arguments.
21
32
  """
22
33
  super().__init__(name)
23
- self.connection_data = kwargs.get("connection_data", {})
34
+ self.connection_data = connection_data
35
+ self.kwargs = kwargs
24
36
 
25
37
  self.connection = None
26
38
  self.is_connected = False
27
39
 
28
- # todo store parsed data in files
40
+ self._register_table("projects", JiraProjectsTable(self))
41
+ self._register_table("issues", JiraIssuesTable(self))
42
+ self._register_table("groups", JiraGroupsTable(self))
43
+ self._register_table("users", JiraUsersTable(self))
29
44
 
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)
42
-
43
- for table_name, resource in resource_tables.items():
44
- self._register_table(table_name, resource)
45
+ def connect(self) -> Jira:
46
+ """
47
+ Establishes a connection to the Jira API.
45
48
 
46
- def __del__(self):
47
- if self.is_connected is True:
48
- self.disconnect()
49
+ Raises:
50
+ ValueError: If the required connection parameters are not provided.
51
+ AuthenticationError: If an authentication error occurs while connecting to the Salesforce API.
49
52
 
50
- def connect(self):
51
- """
52
- Set up the connection required by the handler.
53
53
  Returns:
54
- HandlerStatusResponse
54
+ atlassian.jira.Jira: A connection object to the Jira API.
55
55
  """
56
- return
56
+ if self.is_connected is True:
57
+ return self.connection
58
+
59
+ is_cloud = self.connection_data.get("cloud", True)
60
+
61
+ if is_cloud:
62
+ # Jira Cloud supports API token authentication.
63
+ if not all(key in self.connection_data for key in ['username', 'api_token', 'url']):
64
+ raise ValueError("Required parameters (username, api_token, url) must be provided.")
65
+
66
+ config = {
67
+ "username": self.connection_data['username'],
68
+ "password": self.connection_data['api_token'],
69
+ "url": self.connection_data['url'],
70
+ }
71
+ else:
72
+ # Jira Server supports personal access token authentication or open access.
73
+ if 'url' not in self.connection_data:
74
+ raise ValueError("Required parameter 'url' must be provided.")
75
+
76
+ config = {
77
+ "url": self.connection_data['url'],
78
+ "cloud": False
79
+ }
80
+
81
+ if 'personal_access_token' in self.connection_data:
82
+ config['session'] = ({"Authorization": f"Bearer {self.connection_data['personal_access_token']}"})
83
+
84
+ try:
85
+ self.connection = Jira(**config)
86
+ self.is_connected = True
87
+ return self.connection
88
+ except Exception as unknown_error:
89
+ logger.error(f"Unknown error connecting to Jira, {unknown_error}!")
90
+ raise
57
91
 
58
92
  def check_connection(self) -> StatusResponse:
59
93
  """
60
- Check connection to the handler.
94
+ Checks the status of the connection to the Salesforce API.
95
+
61
96
  Returns:
62
- HandlerStatusResponse
97
+ StatusResponse: An object containing the success status and an error message if an error occurs.
63
98
  """
64
-
65
99
  response = StatusResponse(False)
66
100
 
67
101
  try:
68
- self.api_resource_generator.check_connection()
102
+ connection = self.connect()
103
+ connection.myself()
69
104
  response.success = True
70
- except Exception as e:
71
- logger.error(f"Error connecting to Jira API: {e}!")
72
- response.error_message = e
105
+ except (HTTPError, ValueError) as known_error:
106
+ logger.error(f'Connection check to Jira failed, {known_error}!')
107
+ response.error_message = str(known_error)
108
+ except Exception as unknown_error:
109
+ logger.error(f'Connection check to Jira failed due to an unknown error, {unknown_error}!')
110
+ response.error_message = str(unknown_error)
73
111
 
74
112
  self.is_connected = response.success
113
+
75
114
  return response
115
+
116
+ def native_query(self, query: str) -> Response:
117
+ """
118
+ Executes a native JQL query on Jira and returns the result.
119
+
120
+ Args:
121
+ query (Text): The JQL query to be executed.
122
+
123
+ Returns:
124
+ Response: A response object containing the result of the query or an error message.
125
+ """
126
+ connection = self.connect()
127
+
128
+ try:
129
+ results = connection.jql(query)
130
+ df = JiraIssuesTable(self).normalize(results['issues'])
131
+ response = Response(
132
+ RESPONSE_TYPE.TABLE,
133
+ df
134
+ )
135
+ except HTTPError as http_error:
136
+ logger.error(f'Error running query: {query} on Jira, {http_error}!')
137
+ response = Response(
138
+ RESPONSE_TYPE.ERROR,
139
+ error_code=0,
140
+ error_message=str(http_error)
141
+ )
142
+ except Exception as unknown_error:
143
+ logger.error(f'Error running query: {query} on Jira, {unknown_error}!')
144
+ response = Response(
145
+ RESPONSE_TYPE.ERROR,
146
+ error_code=0,
147
+ error_message=str(unknown_error)
148
+ )
149
+
150
+ return response