44import logging
55import os
66import re
7- from typing import TYPE_CHECKING , Any , BinaryIO , Literal , cast
7+ from typing import TYPE_CHECKING , Any , BinaryIO , Literal , cast , Iterable
88from warnings import warn
99
1010from deprecated import deprecated
@@ -145,7 +145,7 @@ def get_permissions(
145145
146146 return self .get (url , params = params )
147147
148- def get_all_permissions (self ):
148+ def get_all_permissions (self ) -> dict | None :
149149 """
150150 Returns all permissions that are present in the Jira instance -
151151 Global, Project and the global ones added by plugins
@@ -159,7 +159,9 @@ def get_all_permissions(self):
159159 Reference: https://docs.atlassian.com/software/jira/docs/api/REST/8.5.0/#api/2/application-properties
160160 """
161161
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 :
163165 """
164166 Returns an application property
165167 :param key: str
@@ -180,7 +182,7 @@ def get_property(self, key: T_id | None = None, permission_level: str | None = N
180182
181183 return self .get (url , params = params )
182184
183- def set_property (self , property_id : T_id , value : str ):
185+ def set_property (self , property_id : T_id , value : str ) -> dict | None :
184186 """
185187 Modify an application property via PUT. The "value" field present in the PUT will override the existing value.
186188 :param property_id:
@@ -207,15 +209,15 @@ def get_advanced_settings(self) -> dict | None:
207209 Reference: https://docs.atlassian.com/software/jira/docs/api/REST/8.5.0/#api/2/applicationrole
208210 """
209211
210- def get_all_application_roles (self ):
212+ def get_all_application_roles (self ) -> dict | None :
211213 """
212214 Returns all ApplicationRoles in the system
213215 :return:
214216 """
215217 url = self .resource_url ("applicationrole" )
216218 return self .get (url ) or {}
217219
218- def get_application_role (self , role_key : str ):
220+ def get_application_role (self , role_key : str ) -> dict | None :
219221 """
220222 Returns the ApplicationRole with passed key if it exists
221223 :param role_key: str
@@ -242,7 +244,7 @@ def get_attachments_ids_from_issue(self, issue: T_id) -> list[dict[str, str]]:
242244 list_attachments_id .append ({"filename" : attachment ["filename" ], "attachment_id" : attachment ["id" ]})
243245 return list_attachments_id
244246
245- def get_attachment (self , attachment_id : T_id ):
247+ def get_attachment (self , attachment_id : T_id ) -> dict | None :
246248 """
247249 Returns the meta-data for an attachment, including the URI of the actual attached file
248250 :param attachment_id: int
@@ -301,7 +303,7 @@ def download_attachments_from_issue(self, issue: T_id, path: str | None = None,
301303 except Exception as e :
302304 raise e
303305
304- def get_attachment_content (self , attachment_id : T_id ):
306+ def get_attachment_content (self , attachment_id : T_id ) -> dict | None :
305307 """
306308 Returns the content for an attachment
307309 :param attachment_id: int
@@ -311,7 +313,7 @@ def get_attachment_content(self, attachment_id: T_id):
311313 url = f"{ base_url } /content/{ attachment_id } "
312314 return self .get (url , not_json_response = True )
313315
314- def remove_attachment (self , attachment_id : T_id ):
316+ def remove_attachment (self , attachment_id : T_id ) -> dict | None :
315317 """
316318 Remove an attachment from an issue
317319 :param attachment_id: int
@@ -321,7 +323,7 @@ def remove_attachment(self, attachment_id: T_id):
321323 url = f"{ base_url } /{ attachment_id } "
322324 return self .delete (url )
323325
324- def get_attachment_meta (self ):
326+ def get_attachment_meta (self ) -> dict | None :
325327 """
326328 Returns the meta information for an attachments,
327329 specifically if they are enabled and the maximum upload size allowed
@@ -330,7 +332,7 @@ def get_attachment_meta(self):
330332 url = self .resource_url ("attachment/meta" )
331333 return self .get (url )
332334
333- def get_attachment_expand_human (self , attachment_id : T_id ):
335+ def get_attachment_expand_human (self , attachment_id : T_id ) -> dict | None :
334336 """
335337 Returns the information for an expandable attachment in human-readable format
336338 :param attachment_id: int
@@ -340,7 +342,7 @@ def get_attachment_expand_human(self, attachment_id: T_id):
340342 url = f"{ base_url } /{ attachment_id } /expand/human"
341343 return self .get (url )
342344
343- def get_attachment_expand_raw (self , attachment_id : T_id ):
345+ def get_attachment_expand_raw (self , attachment_id : T_id ) -> dict | None :
344346 """
345347 Returns the information for an expandable attachment in raw format
346348 :param attachment_id: int
@@ -362,7 +364,7 @@ def get_audit_records(
362364 filter : str | None = None ,
363365 from_date : str | None = None ,
364366 to_date : str | None = None ,
365- ):
367+ ) -> dict | None :
366368 """
367369 Returns auditing records filtered using provided parameters
368370 :param offset: the number of record from which search starts
@@ -392,7 +394,7 @@ def get_audit_records(
392394 url = self .resource_url ("auditing/record" )
393395 return self .get (url , params = params ) or {}
394396
395- def post_audit_record (self , audit_record : dict | str ):
397+ def post_audit_record (self , audit_record : dict | str ) -> dict | None :
396398 """
397399 Store a record in Audit Log
398400 :param audit_record: json with compat https://docs.atlassian.com/jira/REST/schema/audit-record#
@@ -406,7 +408,7 @@ def post_audit_record(self, audit_record: dict | str):
406408 Reference: https://docs.atlassian.com/software/jira/docs/api/REST/8.5.0/#api/2/avatar
407409 """
408410
409- def get_all_system_avatars (self , avatar_type : str = "user" ):
411+ def get_all_system_avatars (self , avatar_type : str = "user" ) -> dict | None :
410412 """
411413 Returns all system avatars of the given type.
412414 :param avatar_type:
@@ -422,11 +424,11 @@ def get_all_system_avatars(self, avatar_type: str = "user"):
422424 Reference: https://docs.atlassian.com/software/jira/docs/api/REST/8.5.0/#api/2/cluster
423425 """
424426
425- def get_cluster_all_nodes (self ):
427+ def get_cluster_all_nodes (self ) -> dict | None :
426428 url = self .resource_url ("cluster/nodes" )
427429 return self .get (url )
428430
429- def delete_cluster_node (self , node_id : T_id ):
431+ def delete_cluster_node (self , node_id : T_id ) -> dict | None :
430432 """
431433 Delete the node from the cluster if state of node is OFFLINE
432434 :param node_id: str
@@ -436,7 +438,7 @@ def delete_cluster_node(self, node_id: T_id):
436438 url = f"{ base_url } /{ node_id } "
437439 return self .delete (url )
438440
439- def set_node_to_offline (self , node_id : T_id ):
441+ def set_node_to_offline (self , node_id : T_id ) -> dict | None :
440442 """
441443 Change the node's state to offline if the node is reporting as active, but is not alive
442444 :param node_id: str
@@ -446,14 +448,15 @@ def set_node_to_offline(self, node_id: T_id):
446448 url = f"{ base_url } /{ node_id } /offline"
447449 return self .put (url )
448450
449- def get_cluster_alive_nodes (self ):
451+ def get_cluster_alive_nodes (self ) -> list :
450452 """
451453 Get cluster nodes where alive = True
452454 :return: list of node dicts
453455 """
454- return [_ for _ in self .get_cluster_all_nodes () if _ ["alive" ]]
456+ nodes = self .get_cluster_all_nodes ()
457+ return [_ for _ in nodes .values () if _ ["alive" ]] if nodes else []
455458
456- def request_current_index_from_node (self , node_id : T_id ):
459+ def request_current_index_from_node (self , node_id : T_id ) -> dict | None :
457460 """
458461 Request current index from node (the request is processed asynchronously)
459462 :return:
@@ -467,7 +470,7 @@ def request_current_index_from_node(self, node_id: T_id):
467470 Reference: https://confluence.atlassian.com/support/create-a-support-zip-using-the-rest-api-in-data-center-applications-952054641.html
468471 """
469472
470- def generate_support_zip_on_nodes (self , node_ids : list ):
473+ def generate_support_zip_on_nodes (self , node_ids : list ) -> dict | None :
471474 """
472475 Generate a support zip on targeted nodes of a cluster
473476 :param node_ids: list
@@ -477,7 +480,7 @@ def generate_support_zip_on_nodes(self, node_ids: list):
477480 url = "/rest/troubleshooting/latest/support-zip/cluster"
478481 return self .post (url , data = data )
479482
480- def check_support_zip_status (self , cluster_task_id : T_id ):
483+ def check_support_zip_status (self , cluster_task_id : T_id ) -> dict | None :
481484 """
482485 Check status of support zip creation task
483486 :param cluster_task_id: str
@@ -486,7 +489,7 @@ def check_support_zip_status(self, cluster_task_id: T_id):
486489 url = f"/rest/troubleshooting/latest/support-zip/status/cluster/{ cluster_task_id } "
487490 return self .get (url )
488491
489- def download_support_zip (self , file_name : str ):
492+ def download_support_zip (self , file_name : str ) -> bytes :
490493 """
491494 Download created support zip file
492495 :param file_name: str
@@ -500,12 +503,12 @@ def download_support_zip(self, file_name: str):
500503 Reference: https://docs.atlassian.com/software/jira/docs/api/REST/8.5.0/#api/2/cluster/zdu
501504 """
502505
503- def get_cluster_zdu_state (self ):
506+ def get_cluster_zdu_state (self ) -> dict | None :
504507 url = self .resource_url ("cluster/zdu/state" )
505508 return self .get (url )
506509
507510 # Issue Comments
508- def issue_get_comments (self , issue_id : T_id ):
511+ def issue_get_comments (self , issue_id : T_id ) -> dict | None :
509512 """
510513 Get Comments on an Issue.
511514 :param issue_id: Issue ID
@@ -516,7 +519,7 @@ def issue_get_comments(self, issue_id: T_id):
516519 url = f"{ base_url } /{ issue_id } /comment"
517520 return self .get (url )
518521
519- def issues_get_comments_by_id (self , * args ) :
522+ def issues_get_comments_by_id (self , * args : int ) -> dict | None :
520523 """
521524 Get Comments on Multiple Issues
522525 :param *args: int Issue ID's
@@ -847,7 +850,7 @@ def get_filter(self, filter_id: T_id):
847850 url = f"{ base_url } /{ filter_id } "
848851 return self .get (url )
849852
850- def update_filter (self , filter_id : T_id , jql : str , ** kwargs ):
853+ def update_filter (self , filter_id : T_id , jql : str , ** kwargs : Any ):
851854 """
852855 :param filter_id: int
853856 :param jql: str
@@ -1412,7 +1415,7 @@ def issue_field_value_append(self, issue_id_or_key: str, field: str, value: str,
14121415 params = params ,
14131416 )
14141417
1415- def get_issue_labels (self , issue_key : str ):
1418+ def get_issue_labels (self , issue_key : str ) -> dict | None :
14161419 """
14171420 Get issue labels.
14181421 :param issue_key:
@@ -1748,7 +1751,7 @@ def scrap_regex_from_issue(self, issue: str, regex: str):
17481751 except HTTPError as e :
17491752 if e .response .status_code == 404 :
17501753 # Raise ApiError as the documented reason is ambiguous
1751- log .error ("couldn't find issue: " , issue [ "key" ] )
1754+ log .error ("couldn't find issue: " , issue )
17521755 raise ApiNotFoundError (
17531756 "There is no content with the given issue ud,"
17541757 "or the calling user does not have permission to view the issue" ,
@@ -1890,7 +1893,7 @@ def update_issue_remote_link_by_id(
18901893 url = f"{ base_url } /{ issue_key } /remotelink/{ link_id } "
18911894 return self .put (url , data = data )
18921895
1893- def delete_issue_remote_link_by_id (self , issue_key : str , link_id : T_id ):
1896+ def delete_issue_remote_link_by_id (self , issue_key : str , link_id : T_id ) -> dict | None :
18941897 """
18951898 Deletes Remote Link on Issue
18961899 :param issue_key: str
@@ -1900,27 +1903,23 @@ def delete_issue_remote_link_by_id(self, issue_key: str, link_id: T_id):
19001903 url = f"{ base_url } /{ issue_key } /remotelink/{ link_id } "
19011904 return self .delete (url )
19021905
1903- def get_issue_transitions (self , issue_key : str ):
1906+ def get_issue_transitions (self , issue_key : str ) -> list [ dict ] :
19041907 if self .advanced_mode :
1905- return [
1906- {
1907- "name" : transition ["name" ],
1908- "id" : int (transition ["id" ]),
1909- "to" : transition ["to" ]["name" ],
1910- }
1911- for transition in (self .get_issue_transitions_full (issue_key ).json () or {}).get ("transitions" )
1912- ]
1908+ resp = cast (Response , self .get_issue_transitions_full (issue_key ))
1909+ d : dict [str , list ] = resp .json () or {}
19131910 else :
1914- return [
1915- {
1916- "name" : transition ["name" ],
1917- "id" : int (transition ["id" ]),
1918- "to" : transition ["to" ]["name" ],
1919- }
1920- for transition in (self .get_issue_transitions_full (issue_key ) or {}).get ("transitions" )
1921- ]
1911+ d = self .get_issue_transitions_full (issue_key ) or {}
1912+
1913+ return [
1914+ {
1915+ "name" : transition ["name" ],
1916+ "id" : int (transition ["id" ]),
1917+ "to" : transition ["to" ]["name" ],
1918+ }
1919+ for transition in cast (list [dict ], d .get ("transitions" ))
1920+ ]
19221921
1923- def issue_transition (self , issue_key : str , status : str ):
1922+ def issue_transition (self , issue_key : str , status : str ) -> dict | None :
19241923 return self .set_issue_status (issue_key , status )
19251924
19261925 def set_issue_status (
@@ -1979,7 +1978,7 @@ def get_issue_status(self, issue_key: str):
19791978 fields = [("fields" ,), ("status" ,), ("name" ,)]
19801979 return self ._get_response_content (url , fields = fields ) or {}
19811980
1982- def get_issue_status_id (self , issue_key : str ):
1981+ def get_issue_status_id (self , issue_key : str ) -> str :
19831982 base_url = self .resource_url ("issue" )
19841983 url = f"{ base_url } /{ issue_key } ?fields=status"
19851984 fields = [("fields" ,), ("status" ,), ("id" ,)]
0 commit comments