python-jira-plus 0.1.2__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_jira_plus-0.1.2/python_jira_plus.egg-info → python_jira_plus-0.1.3}/PKG-INFO +1 -1
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/python_jira_plus/jira_plus.py +82 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3/python_jira_plus.egg-info}/PKG-INFO +1 -1
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/setup.py +1 -1
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/LICENSE +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/MANIFEST.in +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/README.md +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/pyproject.toml +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/python_jira_plus/__init__.py +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/python_jira_plus/describe_allowed_value.py +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/python_jira_plus.egg-info/SOURCES.txt +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/python_jira_plus.egg-info/dependency_links.txt +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/python_jira_plus.egg-info/requires.txt +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/python_jira_plus.egg-info/top_level.txt +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/setup.cfg +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/usage_example/__init__.py +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/usage_example/create_jira_issue.py +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/usage_example/featch_jira_issues.py +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/usage_example/get_jira_issue.py +0 -0
- {python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/usage_example/update_jira_issue.py +0 -0
|
@@ -6,6 +6,7 @@ import os
|
|
|
6
6
|
import time
|
|
7
7
|
from enum import Enum
|
|
8
8
|
from typing import Any, Union, Optional
|
|
9
|
+
import requests
|
|
9
10
|
from jira import JIRA, JIRAError, Issue
|
|
10
11
|
from jira.client import ResultList
|
|
11
12
|
from retrying import retry
|
|
@@ -312,3 +313,84 @@ class JiraPlus:
|
|
|
312
313
|
except Exception as err:
|
|
313
314
|
self.logger.exception(f"Unexpected error: {err}")
|
|
314
315
|
return False
|
|
316
|
+
|
|
317
|
+
def _get_available_link_types(self) -> set[str]:
|
|
318
|
+
try:
|
|
319
|
+
return {link_type.name for link_type in self.jira_client.issue_link_types()}
|
|
320
|
+
except Exception as err:
|
|
321
|
+
self.logger.exception(f"Failed to retrieve link types from JIRA. \n{err}")
|
|
322
|
+
return set()
|
|
323
|
+
|
|
324
|
+
def create_link(self, issue_key: str, link_type: str, in_issue_key: str) -> bool:
|
|
325
|
+
available_link_types = self._get_available_link_types()
|
|
326
|
+
if link_type not in available_link_types:
|
|
327
|
+
raise ValueError(f"Invalid link type '{link_type}'. Available link types: {available_link_types}")
|
|
328
|
+
|
|
329
|
+
try:
|
|
330
|
+
self.jira_client.create_issue_link(
|
|
331
|
+
type=link_type,
|
|
332
|
+
inwardIssue=issue_key,
|
|
333
|
+
outwardIssue=in_issue_key,
|
|
334
|
+
)
|
|
335
|
+
self.logger.info(f"Link between {issue_key} and {in_issue_key} was created")
|
|
336
|
+
return True
|
|
337
|
+
except JIRAError as err:
|
|
338
|
+
self.logger.exception(f"JIRAError - Link between {issue_key} and {in_issue_key} was not created\n{err}")
|
|
339
|
+
return False
|
|
340
|
+
except Exception as err:
|
|
341
|
+
self.logger.exception(f"Exception - Link between {issue_key} and {in_issue_key} was not created\n{err}")
|
|
342
|
+
return False
|
|
343
|
+
|
|
344
|
+
def transition_issue(
|
|
345
|
+
self,
|
|
346
|
+
issue_key: str,
|
|
347
|
+
transition_name: str,
|
|
348
|
+
fields: Optional[dict] = None,
|
|
349
|
+
comment: Optional[str] = None,
|
|
350
|
+
) -> bool:
|
|
351
|
+
try:
|
|
352
|
+
transitions = self.jira_client.transitions(issue_key)
|
|
353
|
+
transition_names = {t['name'] for t in transitions}
|
|
354
|
+
if transition_name not in transition_names:
|
|
355
|
+
self.logger.error(
|
|
356
|
+
f"Transition '{transition_name}' not found for issue {issue_key}. "
|
|
357
|
+
f"\nAvailable transitions: {transition_names}"
|
|
358
|
+
)
|
|
359
|
+
return False
|
|
360
|
+
|
|
361
|
+
transition_id = next(
|
|
362
|
+
(t['id'] for t in transitions if t['name'].lower() == transition_name.lower()),
|
|
363
|
+
None
|
|
364
|
+
)
|
|
365
|
+
if not transition_id:
|
|
366
|
+
self.logger.error(f"Transition '{transition_name}' not found for issue {issue_key}")
|
|
367
|
+
return False
|
|
368
|
+
|
|
369
|
+
self.jira_client.transition_issue(
|
|
370
|
+
issue=issue_key,
|
|
371
|
+
transition=transition_id,
|
|
372
|
+
fields=fields or {},
|
|
373
|
+
comment=comment or None
|
|
374
|
+
)
|
|
375
|
+
self.logger.info(f"Issue {issue_key} transitioned to '{transition_name}'")
|
|
376
|
+
return True
|
|
377
|
+
except JIRAError as err:
|
|
378
|
+
self.logger.exception(f"JIRAError during transition of {issue_key}: {err}")
|
|
379
|
+
return False
|
|
380
|
+
except Exception as err:
|
|
381
|
+
self.logger.exception(f"Unexpected error during transition of {issue_key}: {err}")
|
|
382
|
+
return False
|
|
383
|
+
|
|
384
|
+
def get_account_data(self, user_mail: str) -> list[dict]:
|
|
385
|
+
jira_rst_url = \
|
|
386
|
+
f'https://{self.jira_username}:{self.jira_token}@{self.base_url}/rest/api/{3}/user/search?query={user_mail}'
|
|
387
|
+
response = requests.get(jira_rst_url)
|
|
388
|
+
return response.json()
|
|
389
|
+
|
|
390
|
+
def get_account_id(self, user_mail: str) -> str:
|
|
391
|
+
data = self.get_account_data(user_mail=user_mail)
|
|
392
|
+
return data[0]['accountId']
|
|
393
|
+
|
|
394
|
+
def get_account_display_name(self, user_display_name: str) -> str:
|
|
395
|
+
data = self.get_account_data(user_mail=user_display_name)
|
|
396
|
+
return data[0]['displayName']
|
|
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name="python-jira-plus",
|
|
8
|
-
version="0.1.
|
|
8
|
+
version="0.1.3",
|
|
9
9
|
author='Avi Zaguri',
|
|
10
10
|
author_email="",
|
|
11
11
|
description="Enhanced Python client for JIRA with better error handling, pagination, and metadata validation",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/python_jira_plus/describe_allowed_value.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_jira_plus-0.1.2 → python_jira_plus-0.1.3}/python_jira_plus.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|