fiddler-client 3.2.0.dev5__tar.gz → 3.3.0__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.
Files changed (116) hide show
  1. {fiddler_client-3.2.0.dev5/fiddler_client.egg-info → fiddler_client-3.3.0}/PKG-INFO +1 -1
  2. fiddler_client-3.3.0/fiddler/VERSION +1 -0
  3. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/alert_rule.py +19 -65
  4. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/xai.py +27 -0
  5. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/libs/semver.py +1 -1
  6. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_alert_rule.py +25 -102
  7. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_xai.py +84 -0
  8. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/constants.py +5 -0
  9. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0/fiddler_client.egg-info}/PKG-INFO +1 -1
  10. fiddler_client-3.2.0.dev5/fiddler/VERSION +0 -1
  11. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/LICENSE.txt +0 -0
  12. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/MANIFEST.in +0 -0
  13. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/PUBLIC.md +0 -0
  14. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/README.md +0 -0
  15. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/__init__.py +0 -0
  16. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/configs.py +0 -0
  17. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/connection.py +0 -0
  18. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/constants/__init__.py +0 -0
  19. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/constants/alert_rule.py +0 -0
  20. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/constants/baseline.py +0 -0
  21. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/constants/common.py +0 -0
  22. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/constants/dataset.py +0 -0
  23. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/constants/events.py +0 -0
  24. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/constants/job.py +0 -0
  25. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/constants/model.py +0 -0
  26. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/constants/model_deployment.py +0 -0
  27. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/constants/xai.py +0 -0
  28. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/decorators.py +0 -0
  29. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/__init__.py +0 -0
  30. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/alert_record.py +0 -0
  31. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/base.py +0 -0
  32. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/baseline.py +0 -0
  33. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/custom_expression.py +0 -0
  34. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/dataset.py +0 -0
  35. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/events.py +0 -0
  36. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/file.py +0 -0
  37. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/job.py +0 -0
  38. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/model.py +0 -0
  39. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/model_artifact.py +0 -0
  40. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/model_deployment.py +0 -0
  41. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/organization.py +0 -0
  42. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/project.py +0 -0
  43. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/surrogate.py +0 -0
  44. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/user.py +0 -0
  45. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/entities/webhook.py +0 -0
  46. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/exceptions.py +0 -0
  47. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/libs/__init__.py +0 -0
  48. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/libs/http_client.py +0 -0
  49. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/libs/json_encoder.py +0 -0
  50. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/packtools/__init__.py +0 -0
  51. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/packtools/gem.py +0 -0
  52. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/packtools/keras_ig_helpers.py +0 -0
  53. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/packtools/project_attributions_helpers.py +0 -0
  54. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/packtools/template_model.py +0 -0
  55. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/__init__.py +0 -0
  56. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/alert_record.py +0 -0
  57. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/alert_rule.py +0 -0
  58. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/base.py +0 -0
  59. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/baseline.py +0 -0
  60. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/custom_expression.py +0 -0
  61. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/custom_features.py +0 -0
  62. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/dataset.py +0 -0
  63. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/events.py +0 -0
  64. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/file.py +0 -0
  65. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/filter_query.py +0 -0
  66. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/job.py +0 -0
  67. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/model.py +0 -0
  68. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/model_deployment.py +0 -0
  69. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/model_schema.py +0 -0
  70. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/model_spec.py +0 -0
  71. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/model_task_params.py +0 -0
  72. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/organization.py +0 -0
  73. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/project.py +0 -0
  74. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/response.py +0 -0
  75. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/server_info.py +0 -0
  76. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/user.py +0 -0
  77. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/webhook.py +0 -0
  78. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/xai.py +0 -0
  79. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/schemas/xai_params.py +0 -0
  80. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/__init__.py +0 -0
  81. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/__init__.py +0 -0
  82. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_alert_record.py +0 -0
  83. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_baseline.py +0 -0
  84. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_custom_metric.py +0 -0
  85. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_dataset.py +0 -0
  86. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_events.py +0 -0
  87. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_files.py +0 -0
  88. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_generate_model.py +0 -0
  89. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_job.py +0 -0
  90. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_mixin.py +0 -0
  91. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_model.py +0 -0
  92. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_model_artifact.py +0 -0
  93. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_model_deployment.py +0 -0
  94. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_model_surrogate.py +0 -0
  95. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_project.py +0 -0
  96. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_segment.py +0 -0
  97. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/apis/test_webhook.py +0 -0
  98. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/conftest.py +0 -0
  99. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/test_connection.py +0 -0
  100. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/test_json_encoder.py +0 -0
  101. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/test_logger.py +0 -0
  102. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/test_utils.py +0 -0
  103. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/tests/utils.py +0 -0
  104. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/utils/__init__.py +0 -0
  105. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/utils/helpers.py +0 -0
  106. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/utils/logger.py +0 -0
  107. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/utils/model_generator.py +0 -0
  108. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/utils/validations.py +0 -0
  109. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/utils/version.py +0 -0
  110. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler/version.py +0 -0
  111. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler_client.egg-info/SOURCES.txt +0 -0
  112. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler_client.egg-info/dependency_links.txt +0 -0
  113. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler_client.egg-info/requires.txt +0 -0
  114. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/fiddler_client.egg-info/top_level.txt +0 -0
  115. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/setup.cfg +0 -0
  116. {fiddler_client-3.2.0.dev5 → fiddler_client-3.3.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fiddler-client
3
- Version: 3.2.0.dev5
3
+ Version: 3.3.0
4
4
  Summary: Python client for Fiddler Platform
5
5
  Home-page: https://fiddler.ai
6
6
  Author: Fiddler Labs
@@ -0,0 +1 @@
1
+ 3.3.0
@@ -65,15 +65,14 @@ class AlertRule(
65
65
 
66
66
  @staticmethod
67
67
  def _get_url(id_: UUID | str | None = None) -> str:
68
- """Get model resource/item url."""
68
+ """Get alert resource url."""
69
69
  url = '/v3/alert-rules'
70
70
  return url if not id_ else f'{url}/{id_}'
71
71
 
72
72
  @staticmethod
73
- def _get_url_v2(id_: UUID | str | None = None) -> str:
74
- """Get model resource/item url."""
75
- url = '/v2/alert-configs'
76
- return url if not id_ else f'{url}/{id_}'
73
+ def _get_notification_url(id_: UUID | str | None = None) -> str:
74
+ """Get alert notification resource url."""
75
+ return f'/v3/alert-rules/{id_}/notification'
77
76
 
78
77
  @classmethod
79
78
  def _from_dict(cls, data: dict) -> AlertRule:
@@ -243,7 +242,7 @@ class AlertRule(
243
242
  def enable_notifications(self) -> None:
244
243
  """Enable notifications for an alert rule"""
245
244
  self._client().patch(
246
- url=self._get_url_v2(id_=self.id), data={'enable_notification': True}
245
+ url=self._get_url(id_=self.id), data={'enable_notification': True}
247
246
  )
248
247
  logger.info(
249
248
  'Notifications have been enabled for alert rule with id: %s', self.id
@@ -253,7 +252,7 @@ class AlertRule(
253
252
  def disable_notifications(self) -> None:
254
253
  """Disable notifications for an alert rule"""
255
254
  self._client().patch(
256
- url=self._get_url_v2(id_=self.id), data={'enable_notification': False}
255
+ url=self._get_url(id_=self.id), data={'enable_notification': False}
257
256
  )
258
257
  logger.info(
259
258
  'Notifications have been disabled for alert rule with id: %s', self.id
@@ -277,20 +276,20 @@ class AlertRule(
277
276
 
278
277
  :return: NotificationConfig object
279
278
  """
280
- notifications = self._get_notifications_dict(
281
- emails=emails,
282
- pagerduty_services=pagerduty_services,
283
- pagerduty_severity=pagerduty_severity,
284
- webhooks=webhooks,
285
- )
279
+ payload: dict[str, Any] = {}
280
+ if emails is not None:
281
+ payload['emails'] = emails
282
+ if pagerduty_services is not None:
283
+ payload['pagerduty_services'] = pagerduty_services
284
+ payload['pagerduty_severity'] = pagerduty_severity
285
+ if webhooks is not None:
286
+ payload['webhooks'] = webhooks
286
287
  response = self._client().patch(
287
- url=self._get_url_v2(id_=self.id),
288
- data={'notifications': notifications},
288
+ url=self._get_notification_url(id_=self.id),
289
+ data=payload,
289
290
  )
290
291
 
291
- return self._get_notifications_from_dict(
292
- response.json()['data']['notifications']
293
- )
292
+ return NotificationConfig(**response.json()['data'])
294
293
 
295
294
  @handle_api_error
296
295
  def get_notification_config(self) -> NotificationConfig:
@@ -300,51 +299,6 @@ class AlertRule(
300
299
  :return: NotificationConfig object
301
300
  """
302
301
 
303
- response = self._client().get(url=self._get_url_v2(id_=self.id))
304
-
305
- return self._get_notifications_from_dict(
306
- response.json()['data']['notifications']
307
- )
308
-
309
- @staticmethod
310
- def _get_notifications_from_dict(notif_dict: dict) -> NotificationConfig:
311
- emails = notif_dict.get('emails', {}).get('email')
312
- notifications: dict = {}
313
- if emails:
314
- notifications['emails'] = [email.strip() for email in emails.split(',')]
315
-
316
- pd_services = notif_dict.get('pagerduty', {}).get('service')
317
- if pd_services:
318
- notifications['pagerduty_services'] = [
319
- pd_service.strip() for pd_service in pd_services.split(',')
320
- ]
321
- notifications['pagerduty_severity'] = notif_dict.get('pagerduty', {}).get(
322
- 'severity'
323
- )
302
+ response = self._client().get(url=self._get_notification_url(id_=self.id))
324
303
 
325
- if notif_dict.get('webhooks'):
326
- notifications['webhooks'] = [
327
- webhook['uuid'] for webhook in notif_dict.get('webhooks', [])
328
- ]
329
-
330
- return NotificationConfig(**notifications)
331
-
332
- @staticmethod
333
- def _get_notifications_dict(
334
- emails: builtins.list[str] | None = None,
335
- pagerduty_services: builtins.list[str] | None = None,
336
- pagerduty_severity: str | None = None,
337
- webhooks: builtins.list[UUID] | None = None,
338
- ) -> dict:
339
- return {
340
- 'emails': {
341
- 'email': ','.join(emails) if emails else '',
342
- },
343
- 'pagerduty': {
344
- 'service': ','.join(pagerduty_services) if pagerduty_services else '',
345
- 'severity': pagerduty_severity or '',
346
- },
347
- 'webhooks': [{'uuid': webhook_uuid} for webhook_uuid in webhooks]
348
- if webhooks
349
- else [],
350
- }
304
+ return NotificationConfig(**response.json()['data'])
@@ -573,3 +573,30 @@ class XaiMixin:
573
573
  'This method is available only for model object generated from '
574
574
  'API response.'
575
575
  )
576
+
577
+ @handle_api_error
578
+ def upload_feature_impact(
579
+ self, feature_impact_map: dict, update: bool = False
580
+ ) -> dict:
581
+ """
582
+ User feature impact method. Currently supported for Tabular models only.
583
+
584
+ :param feature_impact_map: Feature impacts dictionary with feature name as key
585
+ and impact as value
586
+ :param update: Whether the feature impact is being updated or uploaded
587
+
588
+ :return: Dictionary with feature_names, feature_impact_scores, system_generated etc
589
+ """
590
+ self._check_id_attributes()
591
+ payload: dict[str, Any] = {
592
+ 'model_id': self.id,
593
+ 'feature_impact_map': feature_impact_map,
594
+ }
595
+
596
+ url = '/v3/analytics/upload-feature-impact'
597
+
598
+ http_method = self._get_method(update=update)
599
+
600
+ response = http_method(url=url, data=payload)
601
+
602
+ return response.json()['data']
@@ -343,7 +343,7 @@ class VersionInfo:
343
343
  )
344
344
 
345
345
  if len(part) == 1:
346
- part = part[0] # type: ignore
346
+ part = part[0]
347
347
  elif not part:
348
348
  raise IndexError('Version part undefined')
349
349
  return part
@@ -22,6 +22,8 @@ from fiddler.tests.constants import (
22
22
  MODEL_NAME,
23
23
  PROJECT_ID,
24
24
  PROJECT_NAME,
25
+ TEST_EMAILS,
26
+ TEST_WEBHOOKS,
25
27
  URL,
26
28
  )
27
29
  from fiddler.utils.logger import set_logging
@@ -72,70 +74,17 @@ API_RESPONSE_200 = {
72
74
  'kind': 'NORMAL',
73
75
  }
74
76
 
75
- API_RESPONSE_200_V2 = {
77
+ ALERT_NOTIFICATION_API_RESPONSE_200 = {
76
78
  'data': {
77
- 'id': 794,
78
- 'organization_name': 'mainbuild',
79
- 'project_name': PROJECT_NAME,
80
- 'model_id': 285,
81
- 'name': 'test_rule',
82
- 'metric': 'jsd',
83
- 'metric_id': 'jsd',
84
- 'metric_display_name': 'Jensen-Shannon Distance',
85
- 'alert_type': 'drift',
86
- 'alert_type_display_name': 'Data Drift',
87
- 'priority': 'MEDIUM',
88
- 'baseline_name': BASELINE_NAME,
89
- 'feature_names': ['creditscore'],
90
- 'time_bucket': 3600000,
91
- 'category': None,
92
- 'bin_size': 'Hour',
93
- 'compare_to': 'raw_value',
94
- 'condition': 'greater',
95
- 'compare_period': None,
96
- 'warning_threshold': 1.0,
97
- 'critical_threshold': 2.3,
98
- 'is_active': True,
99
- 'created_by': 'admin@fiddler.ai',
100
- 'created_at': '2024-04-23T10:34:14.321895+00:00',
101
- 'last_updated': '2024-04-23T10:34:14.323554+00:00',
102
- 'model_name': 'bank_churn',
103
- 'enable_notification': True,
104
- 'segment': {
105
- 'id': '1c9b551a-808b-4ef0-b67b-e788eaf1e6de',
106
- 'organization_name': 'mainbuild',
107
- 'project_name': 'nick_test_project_11',
108
- 'model_name': 'bank_churn',
109
- 'name': 'xyzab',
110
- 'definition': 'Age > 10',
111
- 'description': 'meh',
112
- 'created_at': '2024-04-23T10:31:52.181550+00:00',
113
- 'created_by': {
114
- 'id': 1,
115
- 'full_name': 'Fiddler Administrator',
116
- 'email': 'admin@fiddler.ai',
117
- },
118
- },
119
- 'project': {'id': PROJECT_ID, 'name': PROJECT_NAME},
120
- 'model': {'id': MODEL_ID, 'name': MODEL_NAME, 'version': 'v1'},
121
- 'baseline': {'id': BASELINE_ID, 'name': BASELINE_NAME},
122
- 'compare_bin_delta': None,
123
- 'uuid': ALERT_RULE_ID,
124
- 'notifications': {
125
- 'pagerduty': {
126
- 'alert_config_uuid': ALERT_RULE_ID,
127
- 'service': '',
128
- 'severity': '',
129
- },
130
- 'emails': {'email': ''},
131
- 'webhooks': [],
132
- },
79
+ 'emails': TEST_EMAILS,
80
+ 'webhooks': TEST_WEBHOOKS,
81
+ 'pagerduty_services': [],
82
+ 'pagerduty_severity': '',
133
83
  },
134
- 'api_version': '2.0',
84
+ 'api_version': '3.0',
135
85
  'kind': 'NORMAL',
136
86
  }
137
87
 
138
-
139
88
  API_RESPONSE_404 = {
140
89
  'error': {
141
90
  'code': 404,
@@ -343,8 +292,8 @@ def test_enable_notifications(caplog) -> None:
343
292
  alert_rule = AlertRule.get(id_=ALERT_RULE_ID)
344
293
 
345
294
  resp = responses.patch(
346
- url=f'{URL}/v2/alert-configs/{ALERT_RULE_ID}',
347
- json=API_RESPONSE_200_V2,
295
+ url=f'{URL}/v3/alert-rules/{ALERT_RULE_ID}',
296
+ json=API_RESPONSE_200,
348
297
  )
349
298
  set_logging(logging.INFO)
350
299
 
@@ -368,8 +317,8 @@ def test_disable_notifications(caplog) -> None:
368
317
  API_RESPONSE_200['enable_notification'] = False
369
318
 
370
319
  resp = responses.patch(
371
- url=f'{URL}/v2/alert-configs/{ALERT_RULE_ID}',
372
- json=API_RESPONSE_200_V2,
320
+ url=f'{URL}/v3/alert-rules/{ALERT_RULE_ID}',
321
+ json=API_RESPONSE_200,
373
322
  )
374
323
 
375
324
  set_logging(logging.INFO)
@@ -389,40 +338,20 @@ def test_set_notifications() -> None:
389
338
  )
390
339
 
391
340
  alert_rule = AlertRule.get(id_=ALERT_RULE_ID)
392
- API_RESPONSE_200_V2['data']['notifications'] = {
393
- 'webhooks': [
394
- {'uuid': 'e20bf4cc-d2cf-4540-baef-d96913b14f1b'},
395
- {'uuid': '6e796fda-0111-4a72-82cd-f0f219e903e1'},
396
- ],
397
- 'emails': {
398
- 'alert_config_uuid': ALERT_RULE_ID,
399
- 'email': 'nikhil@fiddler.ai, admin@fiddler.ai',
400
- },
401
- 'pagerduty': {
402
- 'service': '',
403
- 'alert_config_uuid': ALERT_RULE_ID,
404
- 'severity': '',
405
- },
406
- }
407
- responses.patch(
408
- url=f'{URL}/v2/alert-configs/{ALERT_RULE_ID}',
409
- json=API_RESPONSE_200_V2,
341
+ resp = responses.patch(
342
+ url=f'{URL}/v3/alert-rules/{ALERT_RULE_ID}/notification',
343
+ json=ALERT_NOTIFICATION_API_RESPONSE_200,
410
344
  )
411
345
  notifications = alert_rule.set_notification_config(
412
- emails=['nikhil@fiddler.ai', 'admin@fiddler.ai'],
413
- webhooks=[
414
- 'e20bf4cc-d2cf-4540-baef-d96913b14f1b',
415
- '6e796fda-0111-4a72-82cd-f0f219e903e1',
416
- ],
346
+ emails=TEST_EMAILS,
347
+ webhooks=TEST_WEBHOOKS,
417
348
  )
349
+ assert json.loads(resp.calls[0].request.body) == {
350
+ 'emails': TEST_EMAILS,
351
+ 'webhooks': TEST_WEBHOOKS,
352
+ }
418
353
  assert notifications == NotificationConfig(
419
- **{
420
- 'emails': ['nikhil@fiddler.ai', 'admin@fiddler.ai'],
421
- 'webhooks': [
422
- 'e20bf4cc-d2cf-4540-baef-d96913b14f1b',
423
- '6e796fda-0111-4a72-82cd-f0f219e903e1',
424
- ],
425
- }
354
+ **ALERT_NOTIFICATION_API_RESPONSE_200['data']
426
355
  )
427
356
 
428
357
 
@@ -435,16 +364,10 @@ def test_get_notifications() -> None:
435
364
 
436
365
  alert_rule = AlertRule.get(id_=ALERT_RULE_ID)
437
366
  responses.get(
438
- url=f'{URL}/v2/alert-configs/{ALERT_RULE_ID}',
439
- json=API_RESPONSE_200_V2,
367
+ url=f'{URL}/v3/alert-rules/{ALERT_RULE_ID}/notification',
368
+ json=ALERT_NOTIFICATION_API_RESPONSE_200,
440
369
  )
441
370
  notifications = alert_rule.get_notification_config()
442
371
  assert notifications == NotificationConfig(
443
- **{
444
- 'emails': ['nikhil@fiddler.ai', 'admin@fiddler.ai'],
445
- 'webhooks': [
446
- 'e20bf4cc-d2cf-4540-baef-d96913b14f1b',
447
- '6e796fda-0111-4a72-82cd-f0f219e903e1',
448
- ],
449
- }
372
+ **ALERT_NOTIFICATION_API_RESPONSE_200['data']
450
373
  )
@@ -544,6 +544,41 @@ PRECOMPUTE_FEATURE_IMPORTANCE_JOB_API_RESPONSE_200 = {
544
544
  },
545
545
  }
546
546
 
547
+ USER_FEATURE_IMPACT_RESPONSE_200 = {
548
+ 'data': {
549
+ 'feature_names': [
550
+ 'creditscore',
551
+ 'geography',
552
+ 'gender',
553
+ 'age',
554
+ 'tenure',
555
+ 'balance',
556
+ 'numofproducts',
557
+ 'hascrcard',
558
+ 'isactivemember',
559
+ 'estimatedsalary',
560
+ ],
561
+ 'feature_impact_scores': [
562
+ 0.011580908964862443,
563
+ 0.006309520155042726,
564
+ 0.007567492652213872,
565
+ 0.00477455398879517,
566
+ 0.00026155170582271506,
567
+ 0.0,
568
+ 0.0032795830224845025,
569
+ 0.000988697882581393,
570
+ 0.0,
571
+ 0.0022799670889706025,
572
+ ],
573
+ 'system_generated': False,
574
+ 'model_task': 'BINARY_CLASSIFICATION',
575
+ 'model_input_type': 'TABULAR',
576
+ 'created_at': '2024-06-26 09:34:13.120418+00:00',
577
+ },
578
+ 'api_version': '3.0',
579
+ 'kind': 'NORMAL',
580
+ }
581
+
547
582
  PRECOMPUTE_PREDICTIONS_202_RESPONSE = {
548
583
  'data': {'job': {'id': JOB_ID, 'name': 'Pre-compute predictions'}},
549
584
  'api_version': '3.0',
@@ -568,6 +603,19 @@ PRECOMPUTE_PREDICTIONS_JOB_API_RESPONSE_200 = {
568
603
  },
569
604
  }
570
605
 
606
+ FEATURE_IMPACT_MAP = {
607
+ 'creditscore': 0.011580908964862443,
608
+ 'geography': 0.006309520155042726,
609
+ 'gender': 0.007567492652213872,
610
+ 'age': 0.00477455398879517,
611
+ 'tenure': 0.00026155170582271506,
612
+ 'balance': 0.0,
613
+ 'numofproducts': 0.0032795830224845025,
614
+ 'hascrcard': 0.000988697882581393,
615
+ 'isactivemember': 0.0,
616
+ 'estimatedsalary': 0.0022799670889706025,
617
+ }
618
+
571
619
 
572
620
  @responses.activate
573
621
  def test_explain() -> None:
@@ -937,3 +985,39 @@ def test_update_precompute_predictions() -> None:
937
985
 
938
986
  job_obj = model.precompute_predictions(dataset_id=DATASET_ID, update=True)
939
987
  assert isinstance(job_obj, Job)
988
+
989
+
990
+ @responses.activate
991
+ def test_upload_feature_impact() -> None:
992
+ responses.get(
993
+ url=f'{URL}/v3/models/{MODEL_ID}',
994
+ json=MODEL_API_RESPONSE_200,
995
+ )
996
+ model = Model.get(id_=MODEL_ID)
997
+
998
+ responses.post(
999
+ url=f'{URL}/v3/analytics/upload-feature-impact',
1000
+ json=USER_FEATURE_IMPACT_RESPONSE_200,
1001
+ )
1002
+ assert (
1003
+ model.upload_feature_impact(feature_impact_map=FEATURE_IMPACT_MAP)
1004
+ == USER_FEATURE_IMPACT_RESPONSE_200['data']
1005
+ )
1006
+
1007
+
1008
+ @responses.activate
1009
+ def test_update_feature_impact() -> None:
1010
+ responses.get(
1011
+ url=f'{URL}/v3/models/{MODEL_ID}',
1012
+ json=MODEL_API_RESPONSE_200,
1013
+ )
1014
+ model = Model.get(id_=MODEL_ID)
1015
+
1016
+ responses.put(
1017
+ url=f'{URL}/v3/analytics/upload-feature-impact',
1018
+ json=USER_FEATURE_IMPACT_RESPONSE_200,
1019
+ )
1020
+ assert (
1021
+ model.upload_feature_impact(feature_impact_map=FEATURE_IMPACT_MAP, update=True)
1022
+ == USER_FEATURE_IMPACT_RESPONSE_200['data']
1023
+ )
@@ -20,6 +20,11 @@ DATASET_ID = 'ba6ec4e4-7188-44c5-ba84-c2cb22b4bb00'
20
20
  DATASET_NAME = 'dataset3'
21
21
  BASELINE_ID = 'af05646f-0cef-4638-84c9-0d195df2575d'
22
22
  ALERT_RULE_ID = 'ed8f18e6-c319-4374-8884-71126a6bab85'
23
+ TEST_EMAILS = ['test@fiddler.ai', 'admin@fiddler.ai']
24
+ TEST_WEBHOOKS = [
25
+ 'e20bf4cc-d2cf-4540-baef-d96913b14f1b',
26
+ '6e796fda-0111-4a72-82cd-f0f219e903e1',
27
+ ]
23
28
  BASELINE_NAME = 'test_baseline'
24
29
  MODEL_DEPLOYMENT_ID = 'fc07562a-1a27-4f66-9154-732d3b14b98a'
25
30
  WEBHOOK_ID = 'a5b654eb-15c8-43c8-9d50-9ba6eea9a0ff'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fiddler-client
3
- Version: 3.2.0.dev5
3
+ Version: 3.3.0
4
4
  Summary: Python client for Fiddler Platform
5
5
  Home-page: https://fiddler.ai
6
6
  Author: Fiddler Labs
@@ -1 +0,0 @@
1
- 3.2.0.dev5