Skip to content

Commit 777153e

Browse files
artemsafiyulinArtem Safiiulinyoshiokatsuneo
authored
Update jql.py (jira datasource) to use jira api v3 updated. (#7527)
* Update jql.py (jira datasource) to use jira api v3 updated. * fix spaces in blank lines * Add condition for empty "fields" --------- Co-authored-by: Artem Safiiulin <[email protected]> Co-authored-by: Tsuneo Yoshioka <[email protected]>
1 parent 47b1309 commit 777153e

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

redash/query_runner/jql.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@ def merge(self, set):
3434

3535
def parse_issue(issue, field_mapping): # noqa: C901
3636
result = OrderedDict()
37-
result["key"] = issue["key"]
3837

39-
for k, v in issue["fields"].items(): #
38+
# Handle API v3 response format: key field may be missing, use id as fallback
39+
result["key"] = issue.get("key", issue.get("id", "unknown"))
40+
41+
# Handle API v3 response format: fields may be missing
42+
fields = issue.get("fields", {})
43+
for k, v in fields.items(): #
4044
output_name = field_mapping.get_output_field_name(k)
4145
member_names = field_mapping.get_dict_members(k)
4246

@@ -98,7 +102,9 @@ def parse_issues(data, field_mapping):
98102

99103
def parse_count(data):
100104
results = ResultSet()
101-
results.add_row({"count": data["total"]})
105+
# API v3 may not return 'total' field, fallback to counting issues
106+
count = data.get("total", len(data.get("issues", [])))
107+
results.add_row({"count": count})
102108
return results
103109

104110

@@ -160,18 +166,26 @@ def __init__(self, configuration):
160166
self.syntax = "json"
161167

162168
def run_query(self, query, user):
163-
jql_url = "{}/rest/api/2/search".format(self.configuration["url"])
169+
# Updated to API v3 endpoint, fix double slash issue
170+
jql_url = "{}/rest/api/3/search/jql".format(self.configuration["url"].rstrip("/"))
164171

165172
query = json_loads(query)
166173
query_type = query.pop("queryType", "select")
167174
field_mapping = FieldMapping(query.pop("fieldMapping", {}))
168175

176+
# API v3 requires mandatory jql parameter with restrictions
177+
if "jql" not in query or not query["jql"]:
178+
query["jql"] = "created >= -30d order by created DESC"
179+
169180
if query_type == "count":
170181
query["maxResults"] = 1
171182
query["fields"] = ""
172183
else:
173184
query["maxResults"] = query.get("maxResults", 1000)
174185

186+
if "fields" not in query:
187+
query["fields"] = "*all"
188+
175189
response, error = self.get_response(jql_url, params=query)
176190
if error is not None:
177191
return None, error
@@ -182,17 +196,15 @@ def run_query(self, query, user):
182196
results = parse_count(data)
183197
else:
184198
results = parse_issues(data, field_mapping)
185-
index = data["startAt"] + data["maxResults"]
186199

187-
while data["total"] > index:
188-
query["startAt"] = index
200+
# API v3 uses token-based pagination instead of startAt/total
201+
while not data.get("isLast", True) and "nextPageToken" in data:
202+
query["nextPageToken"] = data["nextPageToken"]
189203
response, error = self.get_response(jql_url, params=query)
190204
if error is not None:
191205
return None, error
192206

193207
data = response.json()
194-
index = data["startAt"] + data["maxResults"]
195-
196208
addl_results = parse_issues(data, field_mapping)
197209
results.merge(addl_results)
198210

0 commit comments

Comments
 (0)