fiddler-client 3.0.5__tar.gz → 3.1.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.0.5/fiddler_client.egg-info → fiddler_client-3.1.0}/PKG-INFO +4 -4
  2. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/PUBLIC.md +3 -3
  3. fiddler_client-3.1.0/fiddler/VERSION +1 -0
  4. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/alert_rule.py +19 -17
  5. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/model.py +91 -21
  6. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/alert_rule.py +17 -9
  7. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/model.py +2 -0
  8. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_alert_rule.py +97 -53
  9. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_generate_model.py +6 -1
  10. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_mixin.py +4 -1
  11. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_model.py +128 -6
  12. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_xai.py +2 -0
  13. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/constants.py +1 -0
  14. {fiddler_client-3.0.5 → fiddler_client-3.1.0/fiddler_client.egg-info}/PKG-INFO +4 -4
  15. fiddler_client-3.0.5/fiddler/VERSION +0 -1
  16. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/LICENSE.txt +0 -0
  17. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/MANIFEST.in +0 -0
  18. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/README.md +0 -0
  19. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/__init__.py +0 -0
  20. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/configs.py +0 -0
  21. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/connection.py +0 -0
  22. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/constants/__init__.py +0 -0
  23. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/constants/alert_rule.py +0 -0
  24. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/constants/baseline.py +0 -0
  25. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/constants/common.py +0 -0
  26. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/constants/dataset.py +0 -0
  27. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/constants/events.py +0 -0
  28. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/constants/job.py +0 -0
  29. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/constants/model.py +0 -0
  30. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/constants/model_deployment.py +0 -0
  31. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/constants/xai.py +0 -0
  32. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/decorators.py +0 -0
  33. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/__init__.py +0 -0
  34. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/alert_record.py +0 -0
  35. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/base.py +0 -0
  36. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/baseline.py +0 -0
  37. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/custom_expression.py +0 -0
  38. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/dataset.py +0 -0
  39. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/events.py +0 -0
  40. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/file.py +0 -0
  41. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/job.py +0 -0
  42. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/model_artifact.py +0 -0
  43. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/model_deployment.py +0 -0
  44. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/organization.py +0 -0
  45. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/project.py +0 -0
  46. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/surrogate.py +0 -0
  47. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/user.py +0 -0
  48. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/webhook.py +0 -0
  49. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/entities/xai.py +0 -0
  50. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/exceptions.py +0 -0
  51. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/libs/__init__.py +0 -0
  52. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/libs/http_client.py +0 -0
  53. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/libs/json_encoder.py +0 -0
  54. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/libs/semver.py +0 -0
  55. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/packtools/__init__.py +0 -0
  56. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/packtools/gem.py +0 -0
  57. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/packtools/keras_ig_helpers.py +0 -0
  58. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/packtools/project_attributions_helpers.py +0 -0
  59. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/packtools/template_model.py +0 -0
  60. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/__init__.py +0 -0
  61. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/alert_record.py +0 -0
  62. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/base.py +0 -0
  63. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/baseline.py +0 -0
  64. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/custom_expression.py +0 -0
  65. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/custom_features.py +0 -0
  66. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/dataset.py +0 -0
  67. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/events.py +0 -0
  68. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/file.py +0 -0
  69. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/filter_query.py +0 -0
  70. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/job.py +0 -0
  71. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/model_deployment.py +0 -0
  72. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/model_schema.py +0 -0
  73. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/model_spec.py +0 -0
  74. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/model_task_params.py +0 -0
  75. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/organization.py +0 -0
  76. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/project.py +0 -0
  77. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/response.py +0 -0
  78. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/server_info.py +0 -0
  79. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/user.py +0 -0
  80. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/webhook.py +0 -0
  81. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/xai.py +0 -0
  82. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/schemas/xai_params.py +0 -0
  83. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/__init__.py +0 -0
  84. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/__init__.py +0 -0
  85. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_alert_record.py +0 -0
  86. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_baseline.py +0 -0
  87. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_custom_metric.py +0 -0
  88. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_dataset.py +0 -0
  89. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_events.py +0 -0
  90. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_files.py +0 -0
  91. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_job.py +0 -0
  92. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_model_artifact.py +0 -0
  93. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_model_deployment.py +0 -0
  94. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_model_surrogate.py +0 -0
  95. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_project.py +0 -0
  96. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_segment.py +0 -0
  97. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/apis/test_webhook.py +0 -0
  98. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/conftest.py +0 -0
  99. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/test_connection.py +0 -0
  100. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/test_json_encoder.py +0 -0
  101. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/test_logger.py +0 -0
  102. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/test_utils.py +0 -0
  103. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/tests/utils.py +0 -0
  104. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/utils/__init__.py +0 -0
  105. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/utils/helpers.py +0 -0
  106. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/utils/logger.py +0 -0
  107. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/utils/model_generator.py +0 -0
  108. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/utils/validations.py +0 -0
  109. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/utils/version.py +0 -0
  110. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler/version.py +0 -0
  111. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler_client.egg-info/SOURCES.txt +0 -0
  112. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler_client.egg-info/dependency_links.txt +0 -0
  113. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler_client.egg-info/requires.txt +0 -0
  114. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/fiddler_client.egg-info/top_level.txt +0 -0
  115. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/setup.cfg +0 -0
  116. {fiddler_client-3.0.5 → fiddler_client-3.1.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fiddler-client
3
- Version: 3.0.5
3
+ Version: 3.1.0
4
4
  Summary: Python client for Fiddler Platform
5
5
  Home-page: https://fiddler.ai
6
6
  Author: Fiddler Labs
@@ -30,16 +30,16 @@ publishing for use with our monitoring features.
30
30
 
31
31
  Requirements
32
32
  ------------
33
- Requires Python >= Python-3.8.0 and pip >= 21.0
33
+ Requires Python >= Python-3.6.3 and pip >= 19.0
34
34
 
35
35
  Installation
36
36
  ------------
37
37
 
38
- $ pip3 install "fiddler-client==3.0.*"
38
+ $ pip3 install fiddler-client
39
39
 
40
40
  API Example Usage
41
41
  -------------
42
- Documentation for the API can be found [here](https://docs.fiddler.ai/reference/about-client-3x). For examples of interacting with our APIs, please check out our [Quick Start Guide](https://docs.fiddler.ai/docs/quick-start) as well as the notebooks found on our [Examples Github](https://github.com/fiddler-labs/fiddler-examples).
42
+ Documentation for the API can be found [here](https://docs.fiddler.ai/reference/about-the-fiddler-client). For examples of interacting with our APIs, please check out our [Quick Start Guide](https://docs.fiddler.ai/docs/quick-start) as well as the notebooks found on our [Examples Github](https://github.com/fiddler-labs/fiddler-examples).
43
43
 
44
44
  Version History
45
45
  -------------
@@ -6,16 +6,16 @@ publishing for use with our monitoring features.
6
6
 
7
7
  Requirements
8
8
  ------------
9
- Requires Python >= Python-3.8.0 and pip >= 21.0
9
+ Requires Python >= Python-3.6.3 and pip >= 19.0
10
10
 
11
11
  Installation
12
12
  ------------
13
13
 
14
- $ pip3 install "fiddler-client==3.0.*"
14
+ $ pip3 install fiddler-client
15
15
 
16
16
  API Example Usage
17
17
  -------------
18
- Documentation for the API can be found [here](https://docs.fiddler.ai/reference/about-client-3x). For examples of interacting with our APIs, please check out our [Quick Start Guide](https://docs.fiddler.ai/docs/quick-start) as well as the notebooks found on our [Examples Github](https://github.com/fiddler-labs/fiddler-examples).
18
+ Documentation for the API can be found [here](https://docs.fiddler.ai/reference/about-the-fiddler-client). For examples of interacting with our APIs, please check out our [Quick Start Guide](https://docs.fiddler.ai/docs/quick-start) as well as the notebooks found on our [Examples Github](https://github.com/fiddler-labs/fiddler-examples).
19
19
 
20
20
  Version History
21
21
  -------------
@@ -0,0 +1 @@
1
+ 3.1.0
@@ -8,8 +8,8 @@ from uuid import UUID
8
8
  from fiddler.constants.alert_rule import AlertCondition, BinSize, CompareTo, Priority
9
9
  from fiddler.decorators import handle_api_error
10
10
  from fiddler.entities.base import BaseEntity
11
- from fiddler.entities.baseline import Baseline, BaselineCompactMixin
12
- from fiddler.entities.model import Model, ModelCompactMixin
11
+ from fiddler.entities.baseline import BaselineCompactMixin
12
+ from fiddler.entities.model import ModelCompactMixin
13
13
  from fiddler.entities.project import ProjectCompactMixin
14
14
  from fiddler.schemas.alert_rule import AlertRuleResp, NotificationConfig
15
15
  from fiddler.schemas.filter_query import OperatorType, QueryCondition, QueryRule
@@ -63,6 +63,12 @@ class AlertRule(
63
63
 
64
64
  @staticmethod
65
65
  def _get_url(id_: UUID | str | None = None) -> str:
66
+ """Get model resource/item url."""
67
+ url = '/v3/alert-rules'
68
+ return url if not id_ else f'{url}/{id_}'
69
+
70
+ @staticmethod
71
+ def _get_url_v2(id_: UUID | str | None = None) -> str:
66
72
  """Get model resource/item url."""
67
73
  url = '/v2/alert-configs'
68
74
  return url if not id_ else f'{url}/{id_}'
@@ -78,7 +84,7 @@ class AlertRule(
78
84
  instance = cls(
79
85
  name=resp_obj.name,
80
86
  model_id=resp_obj.model.id,
81
- metric_id=resp_obj.metric_id,
87
+ metric_id=resp_obj.metric.id,
82
88
  priority=resp_obj.priority,
83
89
  compare_to=resp_obj.compare_to,
84
90
  condition=resp_obj.condition,
@@ -113,11 +119,11 @@ class AlertRule(
113
119
  # Reset properties
114
120
  self.model_id = resp_obj.model.id
115
121
  self.project_id = resp_obj.project.id
122
+ self.metric_id = resp_obj.metric.id
116
123
 
117
124
  # Add remaining fields
118
125
  fields = [
119
126
  'id',
120
- 'metric_id',
121
127
  'created_at',
122
128
  'updated_at',
123
129
  ]
@@ -179,7 +185,9 @@ class AlertRule(
179
185
  if columns:
180
186
  for column in columns:
181
187
  rules.append(
182
- QueryRule(field='columns', operator=OperatorType.ANY, value=column)
188
+ QueryRule(
189
+ field='feature_names', operator=OperatorType.ANY, value=column
190
+ )
183
191
  )
184
192
 
185
193
  _filter = QueryCondition(rules=rules)
@@ -188,7 +196,6 @@ class AlertRule(
188
196
  if ordering:
189
197
  params['ordering'] = ','.join(ordering)
190
198
 
191
- params['organization_name'] = cls.get_organization_name()
192
199
  for rule in cls._paginate(url=cls._get_url(), params=params):
193
200
  yield cls._from_dict(data=rule)
194
201
 
@@ -202,12 +209,9 @@ class AlertRule(
202
209
  @handle_api_error
203
210
  def create(self) -> AlertRule:
204
211
  """Create a new alert rule."""
205
- model = Model.get(self.model_id)
206
212
  payload: dict[str, Any] = {
207
213
  'name': self.name,
208
- 'organization_name': self.organization_name,
209
- 'model_name': model.name,
210
- 'project_name': model.project.name,
214
+ 'model_id': self.model_id,
211
215
  'metric_id': self.metric_id,
212
216
  'priority': self.priority,
213
217
  'compare_to': self.compare_to,
@@ -218,11 +222,9 @@ class AlertRule(
218
222
  'warning_threshold': self.warning_threshold,
219
223
  'feature_names': self.columns,
220
224
  'compare_bin_delta': self.compare_bin_delta,
221
- 'notifications': self._get_notifications_dict(),
222
225
  }
223
226
  if self.baseline_id:
224
- baseline = Baseline.get(self.baseline_id)
225
- payload['baseline_name'] = baseline.name
227
+ payload['baseline_id'] = self.baseline_id
226
228
 
227
229
  response = self._client().post(
228
230
  url=self._get_url(),
@@ -236,7 +238,7 @@ class AlertRule(
236
238
  def enable_notifications(self) -> None:
237
239
  """Enable notifications for an alert rule"""
238
240
  self._client().patch(
239
- url=self._get_url(id_=self.id), data={'enable_notification': True}
241
+ url=self._get_url_v2(id_=self.id), data={'enable_notification': True}
240
242
  )
241
243
  logger.info(
242
244
  'Notifications have been enabled for alert rule with id: %s', self.id
@@ -246,7 +248,7 @@ class AlertRule(
246
248
  def disable_notifications(self) -> None:
247
249
  """Disable notifications for an alert rule"""
248
250
  self._client().patch(
249
- url=self._get_url(id_=self.id), data={'enable_notification': False}
251
+ url=self._get_url_v2(id_=self.id), data={'enable_notification': False}
250
252
  )
251
253
  logger.info(
252
254
  'Notifications have been disabled for alert rule with id: %s', self.id
@@ -277,7 +279,7 @@ class AlertRule(
277
279
  webhooks=webhooks,
278
280
  )
279
281
  response = self._client().patch(
280
- url=self._get_url(id_=self.id),
282
+ url=self._get_url_v2(id_=self.id),
281
283
  data={'notifications': notifications},
282
284
  )
283
285
 
@@ -293,7 +295,7 @@ class AlertRule(
293
295
  :return: NotificationConfig object
294
296
  """
295
297
 
296
- response = self._client().get(url=self._get_url(id_=self.id))
298
+ response = self._client().get(url=self._get_url_v2(id_=self.id))
297
299
 
298
300
  return self._get_notifications_from_dict(
299
301
  response.json()['data']['notifications']
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import builtins
4
4
  import typing
5
+ from copy import deepcopy
5
6
  from dataclasses import dataclass
6
7
  from datetime import datetime
7
8
  from functools import cached_property
@@ -32,12 +33,15 @@ from fiddler.schemas.model_spec import ModelSpec
32
33
  from fiddler.schemas.model_task_params import ModelTaskParams
33
34
  from fiddler.schemas.xai_params import XaiParams
34
35
  from fiddler.utils.helpers import raise_not_found
36
+ from fiddler.utils.logger import get_logger
35
37
  from fiddler.utils.model_generator import ModelGenerator
36
38
 
37
39
  if typing.TYPE_CHECKING:
38
40
  from fiddler.entities.baseline import Baseline
39
41
  from fiddler.entities.dataset import Dataset
40
42
 
43
+ logger = get_logger(__name__)
44
+
41
45
 
42
46
  class Model(
43
47
  BaseEntity,
@@ -52,6 +56,7 @@ class Model(
52
56
  project_id: UUID | str,
53
57
  schema: ModelSchema,
54
58
  spec: ModelSpec,
59
+ version: str | None = None,
55
60
  input_type: str = ModelInputType.TABULAR,
56
61
  task: str = ModelTask.NOT_SET,
57
62
  task_params: ModelTaskParams | None = None,
@@ -63,6 +68,7 @@ class Model(
63
68
  ) -> None:
64
69
  """Construct a model instance"""
65
70
  self.name = name
71
+ self.version = version
66
72
  self.project_id = project_id
67
73
  self.schema = schema
68
74
  self.input_type = input_type
@@ -101,6 +107,7 @@ class Model(
101
107
  # Initialize
102
108
  instance = cls(
103
109
  name=resp_obj.name,
110
+ version=resp_obj.version,
104
111
  schema=resp_obj.schema_,
105
112
  spec=resp_obj.spec,
106
113
  project_id=resp_obj.project.id,
@@ -141,6 +148,7 @@ class Model(
141
148
  fields = [
142
149
  'id',
143
150
  'name',
151
+ 'version',
144
152
  'spec',
145
153
  'input_type',
146
154
  'task',
@@ -188,12 +196,20 @@ class Model(
188
196
 
189
197
  @classmethod
190
198
  @handle_api_error
191
- def from_name(cls, name: str, project_id: UUID | str) -> Model:
199
+ def from_name(
200
+ cls,
201
+ name: str,
202
+ project_id: UUID | str,
203
+ version: str | None = None,
204
+ latest: bool = False,
205
+ ) -> Model:
192
206
  """
193
207
  Get the model instance from model name within a project.
194
208
 
195
209
  :param name: Model name
196
210
  :param project_id: Project identifier
211
+ :param version: Version name
212
+ :param latest: Whether to fetch the latest version of the model or first version
197
213
  :return: Model instance
198
214
  """
199
215
  _filter = QueryCondition(
@@ -207,8 +223,15 @@ class Model(
207
223
  ]
208
224
  )
209
225
 
226
+ if version:
227
+ _filter.add_rule(
228
+ QueryRule(field='version', operator=OperatorType.EQUAL, value=version)
229
+ )
230
+
231
+ ordering = '-created_at' if latest else 'created_at'
210
232
  response = cls._client().get(
211
- url=cls._get_url(), params={'filter': _filter.json()}
233
+ url=cls._get_url(),
234
+ params={'filter': _filter.json(), 'limit': 1, 'ordering': ordering},
212
235
  )
213
236
 
214
237
  if response.json()['data']['total'] == 0:
@@ -219,22 +242,27 @@ class Model(
219
242
  @handle_api_error
220
243
  def create(self) -> Model:
221
244
  """Create a new model."""
245
+ payload = {
246
+ 'name': self.name,
247
+ 'project_id': str(self.project_id),
248
+ 'schema': self.schema.dict(),
249
+ 'spec': self.spec.dict(),
250
+ 'input_type': self.input_type,
251
+ 'task': self.task,
252
+ 'task_params': self.task_params.dict(),
253
+ 'description': self.description,
254
+ 'event_id_col': self.event_id_col,
255
+ 'event_ts_col': self.event_ts_col,
256
+ 'event_ts_format': self.event_ts_format,
257
+ 'xai_params': self.xai_params.dict(),
258
+ }
259
+
260
+ if self.version:
261
+ payload['version'] = self.version
262
+
222
263
  response = self._client().post(
223
264
  url=self._get_url(),
224
- data={
225
- 'name': self.name,
226
- 'project_id': str(self.project_id),
227
- 'schema': self.schema.dict(),
228
- 'spec': self.spec.dict(),
229
- 'input_type': self.input_type,
230
- 'task': self.task,
231
- 'task_params': self.task_params.dict(),
232
- 'description': self.description,
233
- 'event_id_col': self.event_id_col,
234
- 'event_ts_col': self.event_ts_col,
235
- 'event_ts_format': self.event_ts_format,
236
- 'xai_params': self.xai_params.dict(),
237
- },
265
+ data=payload,
238
266
  )
239
267
  self._refresh_from_response(response=response)
240
268
  return self
@@ -243,6 +271,7 @@ class Model(
243
271
  def update(self) -> None:
244
272
  """Update an existing model."""
245
273
  body: dict[str, Any] = {
274
+ 'version': self.version,
246
275
  'xai_params': self.xai_params.dict(),
247
276
  'description': self.description,
248
277
  'event_id_col': self.event_id_col,
@@ -256,13 +285,13 @@ class Model(
256
285
  @classmethod
257
286
  @handle_api_error
258
287
  def list(
259
- cls,
260
- project_id: UUID | str,
288
+ cls, project_id: UUID | str, name: str | None = None
261
289
  ) -> Iterator[ModelCompact]:
262
290
  """
263
291
  Get a list of all models with the given filters
264
292
 
265
293
  :param project_id: Project identifier
294
+ :param name: Model name, use this for listing all the versions of a model
266
295
  :return: ModelCompact iterator
267
296
  """
268
297
  _filter = QueryCondition(
@@ -273,10 +302,43 @@ class Model(
273
302
  ]
274
303
  )
275
304
 
305
+ if name:
306
+ _filter.add_rule(
307
+ QueryRule(field='name', operator=OperatorType.EQUAL, value=name)
308
+ )
309
+
276
310
  params = {'filter': _filter.json()}
277
311
 
278
312
  for model in cls._paginate(url=cls._get_url(), params=params):
279
- yield ModelCompact(id=model['id'], name=model['name'])
313
+ yield ModelCompact(
314
+ id=model['id'], name=model['name'], version=model['version']
315
+ )
316
+
317
+ def duplicate(self, version: str | None = None) -> Model:
318
+ """
319
+ Duplicate the model instance with the given version name.
320
+
321
+ This call will not save the model on server. After making changes to the model
322
+ instance call .create() to add the model version to Fiddler Platform.
323
+
324
+ :param version: Version name for the new instance
325
+ :return: Model instance
326
+ """
327
+ return Model(
328
+ name=self.name,
329
+ project_id=self.project_id,
330
+ schema=deepcopy(self.schema),
331
+ spec=deepcopy(self.spec),
332
+ version=version if version else self.version,
333
+ input_type=self.input_type,
334
+ task=self.task,
335
+ task_params=deepcopy(self.task_params),
336
+ description=self.description,
337
+ event_id_col=self.event_id_col,
338
+ event_ts_col=self.event_ts_col,
339
+ event_ts_format=self.event_ts_format,
340
+ xai_params=deepcopy(self.xai_params),
341
+ )
280
342
 
281
343
  @property
282
344
  def datasets(self) -> Iterator[Dataset]:
@@ -316,6 +378,7 @@ class Model(
316
378
  name: str,
317
379
  project_id: UUID | str,
318
380
  spec: ModelSpec | None = None,
381
+ version: str | None = None,
319
382
  input_type: str = ModelInputType.TABULAR,
320
383
  task: str = ModelTask.NOT_SET,
321
384
  task_params: ModelTaskParams | None = None,
@@ -334,6 +397,7 @@ class Model(
334
397
  :param name: Model name
335
398
  :param project_id: Project identifier
336
399
  :param spec: ModelSpec instance
400
+ :param version: Model version name
337
401
  :param input_type: Model input task type
338
402
  :param task: Model task like Regression, Binary classification etc.
339
403
  :param task_params: Parameters based on the task type
@@ -354,6 +418,7 @@ class Model(
354
418
 
355
419
  return Model(
356
420
  name=name,
421
+ version=version,
357
422
  schema=resp_obj.schema_,
358
423
  spec=resp_obj.spec,
359
424
  project_id=project_id,
@@ -404,7 +469,7 @@ class Model(
404
469
  :return: list[UUID] for list of dicts or dataframe source and Job object for
405
470
  file path source.
406
471
  """
407
-
472
+ logger.info('Model[%s/%s] - Publishing events', self.name, self.version)
408
473
  return self._event_publisher.publish(
409
474
  source=source,
410
475
  environment=environment,
@@ -496,6 +561,7 @@ class Model(
496
561
  class ModelCompact:
497
562
  id: UUID
498
563
  name: str
564
+ version: str | None = None
499
565
 
500
566
  def fetch(self) -> Model:
501
567
  """Fetch model instance"""
@@ -513,4 +579,8 @@ class ModelCompactMixin:
513
579
  'response.'
514
580
  )
515
581
 
516
- return ModelCompact(id=response.model.id, name=response.model.name)
582
+ return ModelCompact(
583
+ id=response.model.id,
584
+ name=response.model.name,
585
+ version=response.model.version,
586
+ )
@@ -12,25 +12,33 @@ from fiddler.schemas.model import ModelCompactResp
12
12
  from fiddler.schemas.project import ProjectCompactResp
13
13
 
14
14
 
15
+ class MetricResp(BaseModel):
16
+ id: Union[str, UUID]
17
+ display_name: str
18
+ type: str
19
+ type_display_name: str
20
+
21
+
15
22
  class AlertRuleResp(BaseModel):
16
- id: UUID = Field(alias='uuid')
23
+ id: UUID
17
24
  name: str
18
- model: ModelCompactResp
19
- project: ProjectCompactResp
20
- baseline: Optional[BaselineCompactResp]
21
- segment: Optional[SegmentCompactResp]
22
25
  priority: Union[str, Priority]
23
26
  compare_to: Union[str, CompareTo]
24
- metric_id: Union[str, UUID]
25
- critical_threshold: float
26
27
  condition: Union[str, AlertCondition]
28
+ compare_bin_delta: Optional[int]
27
29
  bin_size: Union[str, BinSize]
28
30
  columns: Optional[List[str]] = Field(alias='feature_names')
29
- compare_bin_delta: Optional[int]
31
+ critical_threshold: float
30
32
  warning_threshold: Optional[float]
31
33
 
32
34
  created_at: datetime
33
- updated_at: datetime = Field(alias='last_updated')
35
+ updated_at: datetime
36
+
37
+ metric: MetricResp
38
+ model: ModelCompactResp
39
+ project: ProjectCompactResp
40
+ baseline: Optional[BaselineCompactResp]
41
+ segment: Optional[SegmentCompactResp]
34
42
 
35
43
 
36
44
  class NotificationConfig(BaseModel):
@@ -17,11 +17,13 @@ from fiddler.schemas.xai_params import XaiParams
17
17
  class ModelCompactResp(BaseModel):
18
18
  id: UUID
19
19
  name: str
20
+ version: Optional[str]
20
21
 
21
22
 
22
23
  class ModelResp(BaseModel):
23
24
  id: UUID
24
25
  name: str
26
+ version: str
25
27
  input_type: str
26
28
  task: str
27
29
  task_params: ModelTaskParams