Skip to content

Commit 9158584

Browse files
committed
[Jira] Add get_changelogs_bulk method + code style fixes (applied Black formatting to atlassian/, examples/, tests/)
1 parent 63e744f commit 9158584

10 files changed

Lines changed: 70 additions & 21 deletions

File tree

atlassian/confluence/__init__.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@ def __init__(self, url, *args, **kwargs):
2525
if is_cloud is None:
2626
hostname = urlparse(url).hostname or ""
2727
is_cloud = (
28-
hostname == "atlassian.net" or hostname.endswith(".atlassian.net")
29-
or hostname == "jira.com" or hostname.endswith(".jira.com")
30-
or hostname == "api.atlassian.com" or hostname.endswith(".api.atlassian.com")
28+
hostname == "atlassian.net"
29+
or hostname.endswith(".atlassian.net")
30+
or hostname == "jira.com"
31+
or hostname.endswith(".jira.com")
32+
or hostname == "api.atlassian.com"
33+
or hostname.endswith(".api.atlassian.com")
3134
)
3235
if is_cloud:
3336
impl = ConfluenceCloud(url, *args, **kwargs)

atlassian/confluence/cloud/base.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,3 @@ def __init__(self, url, *args, **kwargs):
2323
:return: nothing
2424
"""
2525
super(ConfluenceCloudBase, self).__init__(url, *args, **kwargs)
26-
27-

atlassian/confluence/server/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,9 @@ def get_all_draft_pages_from_space(self, space_key, **kwargs):
297297

298298
def get_all_draft_blog_posts_from_space(self, space_key, **kwargs):
299299
"""Get all draft blog posts from space."""
300-
return self._get_paged("content", params={"spaceKey": space_key, "type": "blogpost", "status": "draft", **kwargs})
300+
return self._get_paged(
301+
"content", params={"spaceKey": space_key, "type": "blogpost", "status": "draft", **kwargs}
302+
)
301303

302304
# Trash Management
303305
def get_trash_content(self, space_key, **kwargs):
@@ -310,7 +312,9 @@ def get_all_pages_from_space_trash(self, space_key, **kwargs):
310312

311313
def get_all_blog_posts_from_space_trash(self, space_key, **kwargs):
312314
"""Get all blog posts from space trash."""
313-
return self._get_paged("content", params={"spaceKey": space_key, "type": "blogpost", "status": "trashed", **kwargs})
315+
return self._get_paged(
316+
"content", params={"spaceKey": space_key, "type": "blogpost", "status": "trashed", **kwargs}
317+
)
314318

315319
# Export
316320
def export_content(self, content_id, **kwargs):

atlassian/confluence/server/base.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,3 @@ def __init__(self, url, *args, **kwargs):
2323
:return: nothing
2424
"""
2525
super(ConfluenceServerBase, self).__init__(url, *args, **kwargs)
26-
27-

atlassian/jira.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,40 @@ def get_issue_changelog(self, issue_key: str, start: Optional[int] = None, limit
14571457
url = f"{base_url}/{issue_key}?expand=changelog"
14581458
return self._get_response_content(url, fields=[("changelog", params)])
14591459

1460+
def get_changelogs_bulk(
1461+
self,
1462+
issue_ids_or_keys: List[str],
1463+
fields_by: Optional[str] = None,
1464+
next_page_token: Optional[str] = None,
1465+
max_results: Optional[int] = None,
1466+
) -> T_resp_json:
1467+
"""
1468+
Returns changelogs for multiple issues in bulk.
1469+
Only Jira Cloud platform.
1470+
1471+
Reference: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-changelog-bulkfetch-post
1472+
1473+
:param issue_ids_or_keys: List of issue IDs or keys to fetch changelogs for. Required.
1474+
:param fields_by: OPTIONAL: Whether to filter changelog entries by field ID or field name.
1475+
Valid values: "id", "name".
1476+
:param next_page_token: OPTIONAL: Token for the next page of results (pagination).
1477+
:param max_results: OPTIONAL: Maximum number of results to return.
1478+
:return: Paginated list of changelogs for the given issues.
1479+
"""
1480+
if not self.cloud:
1481+
raise ValueError("``get_changelogs_bulk`` method is only available for Jira Cloud platform")
1482+
url = self.resource_url("changelog/bulkfetch", api_version=3)
1483+
data: dict = {"issueIdsOrKeys": issue_ids_or_keys}
1484+
if fields_by is not None:
1485+
if fields_by not in ("id", "name"):
1486+
raise ValueError("``fields_by`` must be either 'id' or 'name'")
1487+
data["fieldsByKeys"] = fields_by == "name"
1488+
if next_page_token is not None:
1489+
data["nextPageToken"] = next_page_token
1490+
if max_results is not None:
1491+
data["maxResults"] = int(max_results)
1492+
return self.post(url, data=data)
1493+
14601494
def issue_add_json_worklog(self, key: str, worklog: Union[dict, str]):
14611495
"""
14621496

atlassian/utils.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,14 @@ def block_code_macro_confluence(code, lang=None):
213213
"""
214214
if not lang:
215215
lang = ""
216-
return ("""\
216+
return (
217+
"""\
217218
<ac:structured-macro ac:name="code" ac:schema-version="1">
218219
<ac:parameter ac:name="language">{lang}</ac:parameter>
219220
<ac:plain-text-body><![CDATA[{code}]]></ac:plain-text-body>
220221
</ac:structured-macro>
221-
""").format(lang=lang, code=code)
222+
"""
223+
).format(lang=lang, code=code)
222224

223225

224226
def html_code__macro_confluence(text):
@@ -227,11 +229,13 @@ def html_code__macro_confluence(text):
227229
:param text:
228230
:return:
229231
"""
230-
return ("""\
232+
return (
233+
"""\
231234
<ac:structured-macro ac:name="html" ac:schema-version="1">
232235
<ac:plain-text-body><![CDATA[{text}]]></ac:plain-text-body>
233236
</ac:structured-macro>
234-
""").format(text=text)
237+
"""
238+
).format(text=text)
235239

236240

237241
def noformat_code_macro_confluence(text, nopanel=None):
@@ -243,12 +247,14 @@ def noformat_code_macro_confluence(text, nopanel=None):
243247
"""
244248
if not nopanel:
245249
nopanel = False
246-
return ("""\
250+
return (
251+
"""\
247252
<ac:structured-macro ac:name="noformat" ac:schema-version="1">
248253
<ac:parameter ac:name="nopanel">{nopanel}</ac:parameter>
249254
<ac:plain-text-body><![CDATA[{text}]]></ac:plain-text-body>
250255
</ac:structured-macro>
251-
""").format(nopanel=nopanel, text=text)
256+
"""
257+
).format(nopanel=nopanel, text=text)
252258

253259

254260
def symbol_normalizer(text):

examples/jira/jira_admins_confluence_page.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@
1212

1313
confluence = Confluence(url="http://localhost:8090", username="admin", password="admin")
1414

15-
html = ["""<table>
15+
html = [
16+
"""<table>
1617
<tr>
1718
<th>Project Key</th>
1819
<th>Project Name</th>
1920
<th>Leader</th>
2021
<th>Email</th>
21-
</tr>"""]
22+
</tr>"""
23+
]
2224

2325
for data in jira.project_leaders():
2426
log.info("{project_key} leader is {lead_name} <{lead_email}>".format(**data))

examples/jira/jira_project_administrators.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
<td>{project_name}</td>
1818
<td>{lead_name}</td>
1919
<td><a href="mailto:{lead_email}">{lead_email}</a></td>
20-
</tr>""".format(**data)
20+
</tr>""".format(
21+
**data
22+
)
2123

2224
html += "</table>"
2325

examples/jira/jira_project_leaders.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@
77
jira = Jira(url="http://localhost:8080", username="admin", password="admin")
88

99
EMAIL_SUBJECT = quote("Jira access to project {project_key}")
10-
EMAIL_BODY = quote("""I am asking for access to the {project_key} project in Jira.
10+
EMAIL_BODY = quote(
11+
"""I am asking for access to the {project_key} project in Jira.
1112
1213
To give me the appropriate permissions, assign me to a role on the page:
1314
http://localhost:8080/plugins/servlet/project-config/{project_key}/roles
1415
1516
Role:
1617
Users - read-only access + commenting
1718
Developers - work on tasks, editing, etc.
18-
Admin - Change of configuration and the possibility of starting sprints""")
19+
Admin - Change of configuration and the possibility of starting sprints"""
20+
)
1921

2022
MAILTO = '<a href="mailto:{lead_email}?subject={email_subject}&body={email_body}">{lead_name}</a>'
2123

tests/confluence/test_confluence_cloud.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ def test_pagination_with_relative_next_link_and_base(self, mock_get, confluence_
579579
assert result == [{"id": "1", "title": "Page 1"}, {"id": "2", "title": "Page 2"}]
580580

581581
assert mock_get.call_count == 2
582-
582+
583583
# Verify the second call used scheme+host from self.url (preserving API gateway routing)
584584
args, kwargs = mock_get.call_args_list[1]
585585
assert args[0] == "https://test.atlassian.net/rest/api/content?cursor=1"

0 commit comments

Comments
 (0)