4
4
import logging
5
5
import os
6
6
import re
7
- from typing import TYPE_CHECKING , Any , BinaryIO , Literal , cast
7
+ from typing import TYPE_CHECKING , Any , BinaryIO , Literal , cast , Iterable
8
8
from warnings import warn
9
9
10
10
from deprecated import deprecated
@@ -145,7 +145,7 @@ def get_permissions(
145
145
146
146
return self .get (url , params = params )
147
147
148
- def get_all_permissions (self ):
148
+ def get_all_permissions (self ) -> dict | None :
149
149
"""
150
150
Returns all permissions that are present in the Jira instance -
151
151
Global, Project and the global ones added by plugins
@@ -159,7 +159,9 @@ def get_all_permissions(self):
159
159
Reference: https://docs.atlassian.com/software/jira/docs/api/REST/8.5.0/#api/2/application-properties
160
160
"""
161
161
162
- def get_property (self , key : T_id | None = None , permission_level : str | None = None , key_filter : str | None = None ):
162
+ def get_property (
163
+ self , key : T_id | None = None , permission_level : str | None = None , key_filter : str | None = None
164
+ ) -> dict | None :
163
165
"""
164
166
Returns an application property
165
167
:param key: str
@@ -180,7 +182,7 @@ def get_property(self, key: T_id | None = None, permission_level: str | None = N
180
182
181
183
return self .get (url , params = params )
182
184
183
- def set_property (self , property_id : T_id , value : str ):
185
+ def set_property (self , property_id : T_id , value : str ) -> dict | None :
184
186
"""
185
187
Modify an application property via PUT. The "value" field present in the PUT will override the existing value.
186
188
:param property_id:
@@ -207,15 +209,15 @@ def get_advanced_settings(self) -> dict | None:
207
209
Reference: https://docs.atlassian.com/software/jira/docs/api/REST/8.5.0/#api/2/applicationrole
208
210
"""
209
211
210
- def get_all_application_roles (self ):
212
+ def get_all_application_roles (self ) -> dict | None :
211
213
"""
212
214
Returns all ApplicationRoles in the system
213
215
:return:
214
216
"""
215
217
url = self .resource_url ("applicationrole" )
216
218
return self .get (url ) or {}
217
219
218
- def get_application_role (self , role_key : str ):
220
+ def get_application_role (self , role_key : str ) -> dict | None :
219
221
"""
220
222
Returns the ApplicationRole with passed key if it exists
221
223
:param role_key: str
@@ -242,7 +244,7 @@ def get_attachments_ids_from_issue(self, issue: T_id) -> list[dict[str, str]]:
242
244
list_attachments_id .append ({"filename" : attachment ["filename" ], "attachment_id" : attachment ["id" ]})
243
245
return list_attachments_id
244
246
245
- def get_attachment (self , attachment_id : T_id ):
247
+ def get_attachment (self , attachment_id : T_id ) -> dict | None :
246
248
"""
247
249
Returns the meta-data for an attachment, including the URI of the actual attached file
248
250
:param attachment_id: int
@@ -290,7 +292,7 @@ def download_attachments_from_issue(self, issue: T_id, path: str | None = None,
290
292
except Exception as e :
291
293
raise e
292
294
293
- def get_attachment_content (self , attachment_id : T_id ):
295
+ def get_attachment_content (self , attachment_id : T_id ) -> dict | None :
294
296
"""
295
297
Returns the content for an attachment
296
298
:param attachment_id: int
@@ -300,7 +302,7 @@ def get_attachment_content(self, attachment_id: T_id):
300
302
url = "{base_url}/content/{attachment_id}" .format (base_url = base_url , attachment_id = attachment_id )
301
303
return self .get (url )
302
304
303
- def remove_attachment (self , attachment_id : T_id ):
305
+ def remove_attachment (self , attachment_id : T_id ) -> dict | None :
304
306
"""
305
307
Remove an attachment from an issue
306
308
:param attachment_id: int
@@ -310,7 +312,7 @@ def remove_attachment(self, attachment_id: T_id):
310
312
url = "{base_url}/{attachment_id}" .format (base_url = base_url , attachment_id = attachment_id )
311
313
return self .delete (url )
312
314
313
- def get_attachment_meta (self ):
315
+ def get_attachment_meta (self ) -> dict | None :
314
316
"""
315
317
Returns the meta information for an attachments,
316
318
specifically if they are enabled and the maximum upload size allowed
@@ -319,7 +321,7 @@ def get_attachment_meta(self):
319
321
url = self .resource_url ("attachment/meta" )
320
322
return self .get (url )
321
323
322
- def get_attachment_expand_human (self , attachment_id : T_id ):
324
+ def get_attachment_expand_human (self , attachment_id : T_id ) -> dict | None :
323
325
"""
324
326
Returns the information for an expandable attachment in human-readable format
325
327
:param attachment_id: int
@@ -329,7 +331,7 @@ def get_attachment_expand_human(self, attachment_id: T_id):
329
331
url = "{base_url}/{attachment_id}/expand/human" .format (base_url = base_url , attachment_id = attachment_id )
330
332
return self .get (url )
331
333
332
- def get_attachment_expand_raw (self , attachment_id : T_id ):
334
+ def get_attachment_expand_raw (self , attachment_id : T_id ) -> dict | None :
333
335
"""
334
336
Returns the information for an expandable attachment in raw format
335
337
:param attachment_id: int
@@ -351,7 +353,7 @@ def get_audit_records(
351
353
filter : str | None = None ,
352
354
from_date : str | None = None ,
353
355
to_date : str | None = None ,
354
- ):
356
+ ) -> dict | None :
355
357
"""
356
358
Returns auditing records filtered using provided parameters
357
359
:param offset: the number of record from which search starts
@@ -381,7 +383,7 @@ def get_audit_records(
381
383
url = self .resource_url ("auditing/record" )
382
384
return self .get (url , params = params ) or {}
383
385
384
- def post_audit_record (self , audit_record : dict | str ):
386
+ def post_audit_record (self , audit_record : dict | str ) -> dict | None :
385
387
"""
386
388
Store a record in Audit Log
387
389
:param audit_record: json with compat https://docs.atlassian.com/jira/REST/schema/audit-record#
@@ -395,7 +397,7 @@ def post_audit_record(self, audit_record: dict | str):
395
397
Reference: https://docs.atlassian.com/software/jira/docs/api/REST/8.5.0/#api/2/avatar
396
398
"""
397
399
398
- def get_all_system_avatars (self , avatar_type : str = "user" ):
400
+ def get_all_system_avatars (self , avatar_type : str = "user" ) -> dict | None :
399
401
"""
400
402
Returns all system avatars of the given type.
401
403
:param avatar_type:
@@ -411,11 +413,11 @@ def get_all_system_avatars(self, avatar_type: str = "user"):
411
413
Reference: https://docs.atlassian.com/software/jira/docs/api/REST/8.5.0/#api/2/cluster
412
414
"""
413
415
414
- def get_cluster_all_nodes (self ):
416
+ def get_cluster_all_nodes (self ) -> dict | None :
415
417
url = self .resource_url ("cluster/nodes" )
416
418
return self .get (url )
417
419
418
- def delete_cluster_node (self , node_id : T_id ):
420
+ def delete_cluster_node (self , node_id : T_id ) -> dict | None :
419
421
"""
420
422
Delete the node from the cluster if state of node is OFFLINE
421
423
:param node_id: str
@@ -425,7 +427,7 @@ def delete_cluster_node(self, node_id: T_id):
425
427
url = "{base_url}/{node_id}" .format (base_url = base_url , node_id = node_id )
426
428
return self .delete (url )
427
429
428
- def set_node_to_offline (self , node_id : T_id ):
430
+ def set_node_to_offline (self , node_id : T_id ) -> dict | None :
429
431
"""
430
432
Change the node's state to offline if the node is reporting as active, but is not alive
431
433
:param node_id: str
@@ -435,14 +437,15 @@ def set_node_to_offline(self, node_id: T_id):
435
437
url = "{base_url}/{node_id}/offline" .format (base_url = base_url , node_id = node_id )
436
438
return self .put (url )
437
439
438
- def get_cluster_alive_nodes (self ):
440
+ def get_cluster_alive_nodes (self ) -> list :
439
441
"""
440
442
Get cluster nodes where alive = True
441
443
:return: list of node dicts
442
444
"""
443
- return [_ for _ in self .get_cluster_all_nodes () if _ ["alive" ]]
445
+ nodes = self .get_cluster_all_nodes ()
446
+ return [_ for _ in nodes .values () if _ ["alive" ]] if nodes else []
444
447
445
- def request_current_index_from_node (self , node_id : T_id ):
448
+ def request_current_index_from_node (self , node_id : T_id ) -> dict | None :
446
449
"""
447
450
Request current index from node (the request is processed asynchronously)
448
451
:return:
@@ -456,7 +459,7 @@ def request_current_index_from_node(self, node_id: T_id):
456
459
Reference: https://confluence.atlassian.com/support/create-a-support-zip-using-the-rest-api-in-data-center-applications-952054641.html
457
460
"""
458
461
459
- def generate_support_zip_on_nodes (self , node_ids : list ):
462
+ def generate_support_zip_on_nodes (self , node_ids : list ) -> dict | None :
460
463
"""
461
464
Generate a support zip on targeted nodes of a cluster
462
465
:param node_ids: list
@@ -466,7 +469,7 @@ def generate_support_zip_on_nodes(self, node_ids: list):
466
469
url = "/rest/troubleshooting/latest/support-zip/cluster"
467
470
return self .post (url , data = data )
468
471
469
- def check_support_zip_status (self , cluster_task_id : T_id ):
472
+ def check_support_zip_status (self , cluster_task_id : T_id ) -> dict | None :
470
473
"""
471
474
Check status of support zip creation task
472
475
:param cluster_task_id: str
@@ -475,7 +478,7 @@ def check_support_zip_status(self, cluster_task_id: T_id):
475
478
url = "/rest/troubleshooting/latest/support-zip/status/cluster/{}" .format (cluster_task_id )
476
479
return self .get (url )
477
480
478
- def download_support_zip (self , file_name : str ):
481
+ def download_support_zip (self , file_name : str ) -> bytes :
479
482
"""
480
483
Download created support zip file
481
484
:param file_name: str
@@ -489,12 +492,12 @@ def download_support_zip(self, file_name: str):
489
492
Reference: https://docs.atlassian.com/software/jira/docs/api/REST/8.5.0/#api/2/cluster/zdu
490
493
"""
491
494
492
- def get_cluster_zdu_state (self ):
495
+ def get_cluster_zdu_state (self ) -> dict | None :
493
496
url = self .resource_url ("cluster/zdu/state" )
494
497
return self .get (url )
495
498
496
499
# Issue Comments
497
- def issue_get_comments (self , issue_id : T_id ):
500
+ def issue_get_comments (self , issue_id : T_id ) -> dict | None :
498
501
"""
499
502
Get Comments on an Issue.
500
503
:param issue_id: Issue ID
@@ -505,7 +508,7 @@ def issue_get_comments(self, issue_id: T_id):
505
508
url = "{base_url}/{issue_id}/comment" .format (base_url = base_url , issue_id = issue_id )
506
509
return self .get (url )
507
510
508
- def issues_get_comments_by_id (self , * args ) :
511
+ def issues_get_comments_by_id (self , * args : int ) -> dict | None :
509
512
"""
510
513
Get Comments on Multiple Issues
511
514
:param *args: int Issue ID's
@@ -840,7 +843,7 @@ def get_filter(self, filter_id: T_id):
840
843
url = "{base_url}/{id}" .format (base_url = base_url , id = filter_id )
841
844
return self .get (url )
842
845
843
- def update_filter (self , filter_id : T_id , jql : str , ** kwargs ):
846
+ def update_filter (self , filter_id : T_id , jql : str , ** kwargs : Any ):
844
847
"""
845
848
:param filter_id: int
846
849
:param jql: str
@@ -1407,7 +1410,7 @@ def issue_field_value_append(self, issue_id_or_key: str, field: str, value: str,
1407
1410
params = params ,
1408
1411
)
1409
1412
1410
- def get_issue_labels (self , issue_key : str ):
1413
+ def get_issue_labels (self , issue_key : str ) -> dict | None :
1411
1414
"""
1412
1415
Get issue labels.
1413
1416
:param issue_key:
@@ -1417,7 +1420,11 @@ def get_issue_labels(self, issue_key: str):
1417
1420
url = "{base_url}/{issue_key}?fields=labels" .format (base_url = base_url , issue_key = issue_key )
1418
1421
if self .advanced_mode :
1419
1422
return self .get (url )
1420
- return (self .get (url ) or {}).get ("fields" ).get ("labels" )
1423
+ d = self .get (url ) or {}
1424
+ f = d .get ("fields" )
1425
+ if f :
1426
+ return f .get ("labels" )
1427
+ return None
1421
1428
1422
1429
def update_issue (self , issue_key : T_id , update : dict | str ) -> dict | None :
1423
1430
"""
@@ -1741,7 +1748,7 @@ def scrap_regex_from_issue(self, issue: str, regex: str):
1741
1748
except HTTPError as e :
1742
1749
if e .response .status_code == 404 :
1743
1750
# Raise ApiError as the documented reason is ambiguous
1744
- log .error ("couldn't find issue: " , issue [ "key" ] )
1751
+ log .error ("couldn't find issue: " , issue )
1745
1752
raise ApiNotFoundError (
1746
1753
"There is no content with the given issue ud,"
1747
1754
"or the calling user does not have permission to view the issue" ,
@@ -1882,7 +1889,7 @@ def update_issue_remote_link_by_id(
1882
1889
)
1883
1890
return self .put (url , data = data )
1884
1891
1885
- def delete_issue_remote_link_by_id (self , issue_key : str , link_id : T_id ):
1892
+ def delete_issue_remote_link_by_id (self , issue_key : str , link_id : T_id ) -> dict | None :
1886
1893
"""
1887
1894
Deletes Remote Link on Issue
1888
1895
:param issue_key: str
@@ -1894,27 +1901,23 @@ def delete_issue_remote_link_by_id(self, issue_key: str, link_id: T_id):
1894
1901
)
1895
1902
return self .delete (url )
1896
1903
1897
- def get_issue_transitions (self , issue_key : str ):
1904
+ def get_issue_transitions (self , issue_key : str ) -> list [ dict ] :
1898
1905
if self .advanced_mode :
1899
- return [
1900
- {
1901
- "name" : transition ["name" ],
1902
- "id" : int (transition ["id" ]),
1903
- "to" : transition ["to" ]["name" ],
1904
- }
1905
- for transition in (self .get_issue_transitions_full (issue_key ).json () or {}).get ("transitions" )
1906
- ]
1906
+ resp = cast (Response , self .get_issue_transitions_full (issue_key ))
1907
+ d : dict [str , list ] = resp .json () or {}
1907
1908
else :
1908
- return [
1909
- {
1910
- "name" : transition ["name" ],
1911
- "id" : int (transition ["id" ]),
1912
- "to" : transition ["to" ]["name" ],
1913
- }
1914
- for transition in (self .get_issue_transitions_full (issue_key ) or {}).get ("transitions" )
1915
- ]
1909
+ d = self .get_issue_transitions_full (issue_key ) or {}
1910
+
1911
+ return [
1912
+ {
1913
+ "name" : transition ["name" ],
1914
+ "id" : int (transition ["id" ]),
1915
+ "to" : transition ["to" ]["name" ],
1916
+ }
1917
+ for transition in cast (list [dict ], d .get ("transitions" ))
1918
+ ]
1916
1919
1917
- def issue_transition (self , issue_key : str , status : str ):
1920
+ def issue_transition (self , issue_key : str , status : str ) -> dict | None :
1918
1921
return self .set_issue_status (issue_key , status )
1919
1922
1920
1923
def set_issue_status (
@@ -1970,12 +1973,12 @@ def set_issue_status_by_transition_id(self, issue_key: str, transition_id: T_id)
1970
1973
def get_issue_status (self , issue_key : str ):
1971
1974
base_url = self .resource_url ("issue" )
1972
1975
url = "{base_url}/{issue_key}?fields=status" .format (base_url = base_url , issue_key = issue_key )
1973
- return ((( self .get (url ) or {}).get ("fields" ) or {}). get ("status" ) or {}). get ("name" ) or {}
1976
+ return (self .get (url ) or {}).__getitem__ ("fields" ). __getitem__ ("status" ). __getitem__ ("name" )
1974
1977
1975
- def get_issue_status_id (self , issue_key : str ):
1978
+ def get_issue_status_id (self , issue_key : str ) -> str :
1976
1979
base_url = self .resource_url ("issue" )
1977
1980
url = "{base_url}/{issue_key}?fields=status" .format (base_url = base_url , issue_key = issue_key )
1978
- return (self .get (url ) or {}).get ("fields" ).get ("status" ).get ("id" )
1981
+ return (self .get (url ) or {}).__getitem__ ("fields" ).__getitem__ ("status" ).__getitem__ ("id" )
1979
1982
1980
1983
def get_issue_transitions_full (
1981
1984
self , issue_key : str , transition_id : T_id | None = None , expand : str | None = None
@@ -3160,7 +3163,7 @@ def get_assignable_users_for_issue(
3160
3163
def get_status_id_from_name (self , status_name : str ):
3161
3164
base_url = self .resource_url ("status" )
3162
3165
url = "{base_url}/{name}" .format (base_url = base_url , name = status_name )
3163
- return int ((self .get (url ) or {}).get ("id" ))
3166
+ return int ((self .get (url ) or {}).__getitem__ ("id" ))
3164
3167
3165
3168
def get_status_for_project (self , project_key : str ):
3166
3169
base_url = self .resource_url ("project" )
@@ -3878,7 +3881,7 @@ def get_issue_security_scheme(self, scheme_id: T_id, only_levels: bool = False):
3878
3881
url = "{base_url}/{scheme_id}" .format (base_url = base_url , scheme_id = scheme_id )
3879
3882
3880
3883
if only_levels is True :
3881
- return self .get (url ). get ("levels" )
3884
+ return ( self .get (url ) or {}). __getitem__ ("levels" )
3882
3885
else :
3883
3886
return self .get (url )
3884
3887
0 commit comments