python-jira-plus 1.0.6__tar.gz → 1.0.8__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-jira-plus
3
- Version: 1.0.6
3
+ Version: 1.0.8
4
4
  Summary: Enhanced Python client for JIRA with better error handling, pagination, and metadata validation.
5
5
  Home-page: https://github.com/aviz92/python-jira-plus
6
6
  Author: Avi Zaguri
@@ -25,7 +25,11 @@ def _(value: str, allowed_values: list = None):
25
25
 
26
26
  @describe_allowed_value.register
27
27
  def _(value: list, allowed_values: list = None):
28
- return any(v in allowed_values for v in value)
28
+ if all(isinstance(v, (str, int, float)) for v in value):
29
+ return any(v in allowed_values for v in value)
30
+ if all(isinstance(v, dict) for v in value):
31
+ return any([list(v.values())[0] in allowed_values for v in value])
32
+ return False
29
33
 
30
34
 
31
35
  @describe_allowed_value.register
@@ -51,7 +51,8 @@ class JiraPlus:
51
51
  self.jira_client = self.create_connection()
52
52
  self.check_client_connection()
53
53
 
54
- @retry(stop_max_attempt_number=3, wait_fixed=180000) # Retry 3 times with a 3-min (180000) delay between each attempt
54
+ @retry(stop_max_attempt_number=3,
55
+ wait_fixed=180000) # Retry 3 times with a 3-min (180000) delay between each attempt
55
56
  def create_connection(self, timeout=580) -> Optional[JIRA]:
56
57
  if self.server_type == ServerType.ON_PREMISE and not self.sso:
57
58
  jira_client = JIRA(
@@ -197,13 +198,16 @@ class JiraPlus:
197
198
  """
198
199
  Returns the allowed values for a specific field in a project + issue type context.
199
200
  """
200
- _, issue_meta = self._fetch_metadata(project_key=project_key, issue_type=issue_type)
201
+ fields_metadata = self.get_project_fields_metadata(
202
+ project_key=project_key,
203
+ issue_type=issue_type
204
+ )
201
205
 
202
206
  # Try to find by ID or fallback to case-insensitive name
203
- field = issue_meta['fields'].get(field_id_or_name)
207
+ field = fields_metadata.get(field_id_or_name)
204
208
  if not field:
205
209
  # Try matching by name (case-insensitive)
206
- for fid, fmeta in issue_meta['fields'].items():
210
+ for fid, fmeta in fields_metadata.items():
207
211
  if fmeta['name'].lower() == field_id_or_name.lower():
208
212
  field = fmeta
209
213
  break
@@ -225,28 +229,53 @@ class JiraPlus:
225
229
  allowed_values = allowed_names | allowed_keys
226
230
  return describe_allowed_value(value, allowed_values=allowed_values)
227
231
 
232
+ def get_server_version(self):
233
+ return tuple(self.jira_client.server_info()['versionNumbers'])
234
+
235
+ def check_server_createmeta_compatibility(self) -> bool:
236
+ server_version = self.get_server_version()
237
+ if self.server_type == ServerType.ON_PREMISE and ''.join(str(x) for x in server_version) > '9.0.0':
238
+ self.logger.warning(
239
+ f"JIRA server version {server_version} is below the minimum required version (9.0.0). "
240
+ "Some features may not work as expected."
241
+ )
242
+ return False
243
+ return True
244
+
245
+ def get_project_fields_metadata(self, project_key: str, issue_type: str) -> dict:
246
+ if self.check_server_createmeta_compatibility():
247
+ meta, issue_meta = self._fetch_metadata(project_key=project_key, issue_type=issue_type)
248
+ return issue_meta['fields']
249
+ else:
250
+ _project_issue_types = self.jira_client.project_issue_types(project_key)
251
+ _issue_types = {t.name: t for t in _project_issue_types}
252
+ field_list = self.jira_client.project_issue_fields(project_key, _issue_types[issue_type].id)
253
+ return {f.fieldId: f.raw for f in field_list}
254
+
228
255
  def validate_fields(
229
256
  self,
230
257
  project_key: str,
231
258
  issue_type: str,
232
259
  fields: Optional[dict] = None
233
260
  ) -> None:
234
- meta, issue_meta = self._fetch_metadata(project_key=project_key, issue_type=issue_type)
235
- field_types = meta['projects'][0]['issuetypes'][0]['fields']
261
+ fields_metadata = self.get_project_fields_metadata(
262
+ project_key=project_key,
263
+ issue_type=issue_type
264
+ )
236
265
  for custom_field, value in fields.items():
237
- if custom_field not in issue_meta['fields']:
266
+ if custom_field not in fields_metadata:
238
267
  raise ValueError(
239
268
  f'Invalid field(s) for project "{project_key}", issue type "{issue_type}": "{custom_field}"'
240
269
  )
241
270
 
242
- if allowed_value := issue_meta['fields'][custom_field].get('allowedValues'):
271
+ if allowed_value := fields_metadata[custom_field].get('allowedValues'):
243
272
  if not self._is_value_allowed(value=value, allowed_values=allowed_value):
244
273
  raise ValueError(
245
274
  f"Invalid value '{value}' for field '{custom_field}' in project '{project_key}' with issue type '{issue_type}'."
246
275
  f"The allowed values are: {json.dumps(allowed_value, indent=4, sort_keys=True)}"
247
276
  )
248
277
 
249
- field_type = field_types[custom_field]['schema']['type']
278
+ field_type = fields_metadata[custom_field]['schema']['type']
250
279
  if field_type == 'string' and not isinstance(value, str):
251
280
  raise ValueError(f"Field '{custom_field}' must be a string")
252
281
  elif field_type == 'number' and not isinstance(value, (int, float)):
@@ -260,7 +289,6 @@ class JiraPlus:
260
289
  elif field_type == 'issuetype' and not isinstance(value, dict):
261
290
  raise ValueError(f"Field '{custom_field}' must be an issue type")
262
291
  # Add more field type checks as needed
263
- return issue_meta['fields'].keys()
264
292
 
265
293
  def create_issue(
266
294
  self,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-jira-plus
3
- Version: 1.0.6
3
+ Version: 1.0.8
4
4
  Summary: Enhanced Python client for JIRA with better error handling, pagination, and metadata validation.
5
5
  Home-page: https://github.com/aviz92/python-jira-plus
6
6
  Author: Avi Zaguri
@@ -1,6 +1,6 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
- package_version = '1.0.6'
3
+ package_version = '1.0.8'
4
4
 
5
5
  package_name = 'python-jira-plus'
6
6
  package_description = 'Enhanced Python client for JIRA with better error handling, pagination, and metadata validation.'