Coverage for mindsdb / integrations / handlers / jira_handler / jira_handler.py: 3%
66 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
1from typing import Any, Dict
3from atlassian import Jira
4from requests.exceptions import HTTPError
6from mindsdb.integrations.handlers.jira_handler.jira_tables import (
7 JiraProjectsTable,
8 JiraIssuesTable,
9 JiraUsersTable,
10 JiraGroupsTable,
11)
12from mindsdb.integrations.libs.api_handler import APIHandler
13from mindsdb.integrations.libs.response import (
14 HandlerResponse as Response,
15 HandlerStatusResponse as StatusResponse,
16 RESPONSE_TYPE,
17)
18from mindsdb.utilities import log
21logger = log.getLogger(__name__)
24class JiraHandler(APIHandler):
25 """
26 This handler handles the connection and execution of SQL statements on Jira.
27 """
29 def __init__(self, name: str, connection_data: Dict, **kwargs: Any) -> None:
30 """
31 Initializes the handler.
33 Args:
34 name (Text): The name of the handler instance.
35 connection_data (Dict): The connection data required to connect to the Jira API.
36 kwargs: Arbitrary keyword arguments.
37 """
38 super().__init__(name)
39 self.connection_data = connection_data
40 self.kwargs = kwargs
42 self.connection = None
43 self.is_connected = False
45 self._register_table("projects", JiraProjectsTable(self))
46 self._register_table("issues", JiraIssuesTable(self))
47 self._register_table("groups", JiraGroupsTable(self))
48 self._register_table("users", JiraUsersTable(self))
50 def connect(self) -> Jira:
51 """
52 Establishes a connection to the Jira API.
54 Raises:
55 ValueError: If the required connection parameters are not provided.
56 AuthenticationError: If an authentication error occurs while connecting to the Salesforce API.
58 Returns:
59 atlassian.jira.Jira: A connection object to the Jira API.
60 """
61 if self.is_connected is True:
62 return self.connection
64 is_cloud = self.connection_data.get("cloud", True)
66 if is_cloud:
67 # Jira Cloud supports API token authentication.
68 if not all(key in self.connection_data for key in ["username", "api_token", "url"]):
69 raise ValueError("Required parameters (username, api_token, url) must be provided.")
71 config = {
72 "username": self.connection_data["username"],
73 "password": self.connection_data["api_token"],
74 "url": self.connection_data["url"],
75 "cloud": is_cloud,
76 }
77 else:
78 # Jira Server supports personal access token authentication or open access.
79 if "url" not in self.connection_data:
80 raise ValueError("Required parameter 'url' must be provided.")
82 config = {"url": self.connection_data["url"], "cloud": False}
84 if "personal_access_token" in self.connection_data:
85 config["session"] = {"Authorization": f"Bearer {self.connection_data['personal_access_token']}"}
87 try:
88 self.connection = Jira(**config)
89 self.is_connected = True
90 return self.connection
91 except Exception as unknown_error:
92 logger.error(f"Unknown error connecting to Jira, {unknown_error}!")
93 raise
95 def check_connection(self) -> StatusResponse:
96 """
97 Checks the status of the connection to the Salesforce API.
99 Returns:
100 StatusResponse: An object containing the success status and an error message if an error occurs.
101 """
102 response = StatusResponse(False)
104 try:
105 connection = self.connect()
106 connection.myself()
107 response.success = True
108 except (HTTPError, ValueError) as known_error:
109 logger.error(f"Connection check to Jira failed, {known_error}!")
110 response.error_message = str(known_error)
111 except Exception as unknown_error:
112 logger.error(f"Connection check to Jira failed due to an unknown error, {unknown_error}!")
113 response.error_message = str(unknown_error)
115 self.is_connected = response.success
117 return response
119 def native_query(self, query: str) -> Response:
120 """
121 Executes a native JQL query on Jira and returns the result.
123 Args:
124 query (Text): The JQL query to be executed.
126 Returns:
127 Response: A response object containing the result of the query or an error message.
128 """
129 connection = self.connect()
131 try:
132 results = connection.jql(query)
133 df = JiraIssuesTable(self).normalize(results["issues"])
134 response = Response(RESPONSE_TYPE.TABLE, df)
135 except HTTPError as http_error:
136 logger.error(f"Error running query: {query} on Jira, {http_error}!")
137 response = Response(RESPONSE_TYPE.ERROR, error_code=0, error_message=str(http_error))
138 except Exception as unknown_error:
139 logger.error(f"Error running query: {query} on Jira, {unknown_error}!")
140 response = Response(RESPONSE_TYPE.ERROR, error_code=0, error_message=str(unknown_error))
142 return response