fiddler-client 3.0.0.dev8__tar.gz → 3.0.0.dev10__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 (117) hide show
  1. {fiddler-client-3.0.0.dev8/fiddler_client.egg-info → fiddler-client-3.0.0.dev10}/PKG-INFO +1 -1
  2. fiddler-client-3.0.0.dev10/fiddler/VERSION +1 -0
  3. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/__init__.py +1 -1
  4. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/configs.py +1 -1
  5. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/constants/baseline.py +0 -1
  6. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/alert_rule.py +7 -17
  7. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/baseline.py +13 -20
  8. fiddler-client-3.0.0.dev8/fiddler/entities/custom_metric.py → fiddler-client-3.0.0.dev10/fiddler/entities/custom_expression.py +56 -47
  9. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/dataset.py +8 -14
  10. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/file.py +6 -9
  11. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/model.py +28 -12
  12. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/model_artifact.py +1 -1
  13. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/model_deployment.py +1 -1
  14. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/project.py +2 -0
  15. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/surrogate.py +3 -3
  16. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/xai.py +3 -3
  17. fiddler-client-3.0.0.dev8/fiddler/schemas/custom_metric.py → fiddler-client-3.0.0.dev10/fiddler/schemas/custom_expression.py +10 -2
  18. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_alert_rule.py +2 -2
  19. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_baseline.py +8 -10
  20. fiddler-client-3.0.0.dev10/fiddler/tests/apis/test_custom_metric.py +311 -0
  21. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_dataset.py +8 -13
  22. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_model.py +9 -5
  23. fiddler-client-3.0.0.dev10/fiddler/tests/apis/test_segment.py +311 -0
  24. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10/fiddler_client.egg-info}/PKG-INFO +1 -1
  25. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler_client.egg-info/SOURCES.txt +3 -2
  26. fiddler-client-3.0.0.dev8/fiddler/VERSION +0 -1
  27. fiddler-client-3.0.0.dev8/fiddler/tests/apis/test_custom_metric.py +0 -352
  28. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/LICENSE.txt +0 -0
  29. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/MANIFEST.in +0 -0
  30. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/PUBLIC.md +0 -0
  31. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/README.md +0 -0
  32. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/connection.py +0 -0
  33. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/constants/__init__.py +0 -0
  34. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/constants/alert_rule.py +0 -0
  35. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/constants/common.py +0 -0
  36. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/constants/dataset.py +0 -0
  37. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/constants/events.py +0 -0
  38. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/constants/job.py +0 -0
  39. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/constants/model.py +0 -0
  40. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/constants/model_deployment.py +0 -0
  41. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/constants/xai.py +0 -0
  42. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/decorators.py +0 -0
  43. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/__init__.py +0 -0
  44. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/alert_record.py +0 -0
  45. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/base.py +0 -0
  46. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/events.py +0 -0
  47. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/job.py +0 -0
  48. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/organization.py +0 -0
  49. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/user.py +0 -0
  50. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/entities/webhook.py +0 -0
  51. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/exceptions.py +0 -0
  52. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/libs/__init__.py +0 -0
  53. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/libs/http_client.py +0 -0
  54. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/libs/json_encoder.py +0 -0
  55. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/libs/semver.py +0 -0
  56. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/packtools/__init__.py +0 -0
  57. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/packtools/gem.py +0 -0
  58. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/packtools/keras_ig_helpers.py +0 -0
  59. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/packtools/project_attributions_helpers.py +0 -0
  60. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/packtools/template_model.py +0 -0
  61. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/__init__.py +0 -0
  62. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/alert_record.py +0 -0
  63. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/alert_rule.py +0 -0
  64. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/base.py +0 -0
  65. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/baseline.py +0 -0
  66. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/custom_features.py +0 -0
  67. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/dataset.py +0 -0
  68. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/events.py +0 -0
  69. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/file.py +0 -0
  70. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/filter_query.py +0 -0
  71. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/job.py +0 -0
  72. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/model.py +0 -0
  73. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/model_deployment.py +0 -0
  74. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/model_schema.py +0 -0
  75. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/model_spec.py +0 -0
  76. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/model_task_params.py +0 -0
  77. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/organization.py +0 -0
  78. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/project.py +0 -0
  79. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/response.py +0 -0
  80. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/server_info.py +0 -0
  81. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/user.py +0 -0
  82. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/webhook.py +0 -0
  83. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/xai.py +0 -0
  84. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/schemas/xai_params.py +0 -0
  85. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/__init__.py +0 -0
  86. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/__init__.py +0 -0
  87. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_alert_record.py +0 -0
  88. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_events.py +0 -0
  89. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_files.py +0 -0
  90. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_generate_model.py +0 -0
  91. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_job.py +0 -0
  92. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_mixin.py +0 -0
  93. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_model_artifact.py +0 -0
  94. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_model_deployment.py +0 -0
  95. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_model_surrogate.py +0 -0
  96. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_project.py +0 -0
  97. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_webhook.py +0 -0
  98. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/apis/test_xai.py +0 -0
  99. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/conftest.py +0 -0
  100. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/constants.py +0 -0
  101. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/test_connection.py +0 -0
  102. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/test_json_encoder.py +0 -0
  103. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/test_logger.py +0 -0
  104. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/test_utils.py +0 -0
  105. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/tests/utils.py +0 -0
  106. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/utils/__init__.py +0 -0
  107. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/utils/helpers.py +0 -0
  108. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/utils/logger.py +0 -0
  109. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/utils/model_generator.py +0 -0
  110. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/utils/validations.py +0 -0
  111. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/utils/version.py +0 -0
  112. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler/version.py +0 -0
  113. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler_client.egg-info/dependency_links.txt +0 -0
  114. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler_client.egg-info/requires.txt +0 -0
  115. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/fiddler_client.egg-info/top_level.txt +0 -0
  116. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/setup.cfg +0 -0
  117. {fiddler-client-3.0.0.dev8 → fiddler-client-3.0.0.dev10}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fiddler-client
3
- Version: 3.0.0.dev8
3
+ Version: 3.0.0.dev10
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.0.0.dev10
@@ -20,7 +20,7 @@ from fiddler.constants.xai import ExplainMethod # noqa
20
20
  from fiddler.entities.alert_record import AlertRecord # noqa
21
21
  from fiddler.entities.alert_rule import AlertRule # noqa
22
22
  from fiddler.entities.baseline import Baseline # noqa
23
- from fiddler.entities.custom_metric import CustomMetric, Segment # noqa
23
+ from fiddler.entities.custom_expression import CustomMetric, Segment # noqa
24
24
  from fiddler.entities.dataset import Dataset # noqa
25
25
  from fiddler.entities.file import File # noqa
26
26
  from fiddler.entities.job import Job # noqa
@@ -1,5 +1,5 @@
1
1
  DEFAULT_CONNECTION_TIMEOUT = 60 # In seconds
2
- MIN_SERVER_VERSION = '23.7.0' # @TODO: Change this before 3.0 release
2
+ MIN_SERVER_VERSION = '24.4.0'
3
3
  DEFAULT_PAGE_SIZE = 50
4
4
  JOB_POLL_INTERVAL = 3
5
5
  JOB_WAIT_TIMEOUT = 1800
@@ -9,7 +9,6 @@ class BaselineType(str, enum.Enum):
9
9
 
10
10
  @enum.unique
11
11
  class WindowSize(enum.IntEnum):
12
- FIVE_MINUTES = 300
13
12
  ONE_HOUR = 3600
14
13
  ONE_DAY = 86400
15
14
  ONE_WEEK = 604800
@@ -24,7 +24,7 @@ class AlertRule(
24
24
  def __init__( # pylint: disable=too-many-arguments
25
25
  self,
26
26
  name: str,
27
- model_id: UUID,
27
+ model_id: UUID | str,
28
28
  metric_id: str | UUID,
29
29
  priority: Priority | str,
30
30
  compare_to: CompareTo | str,
@@ -33,7 +33,7 @@ class AlertRule(
33
33
  critical_threshold: float,
34
34
  warning_threshold: float | None = None,
35
35
  columns: list[str] | None = None,
36
- baseline_id: UUID | None = None,
36
+ baseline_id: UUID | str | None = None,
37
37
  compare_bin_delta: int | None = None,
38
38
  ) -> None:
39
39
  """Construct a alert rule instance."""
@@ -140,18 +140,16 @@ class AlertRule(
140
140
  @handle_api_error
141
141
  def list( # pylint: disable=too-many-arguments
142
142
  cls,
143
- model_id: UUID | None = None,
144
- project_id: UUID | None = None,
143
+ model_id: UUID | str,
145
144
  metric_id: UUID | str | None = None,
146
145
  columns: list[str] | None = None,
147
- baseline_id: UUID | None = None,
146
+ baseline_id: UUID | str | None = None,
148
147
  ordering: list[str] | None = None,
149
148
  ) -> Iterator[AlertRule]:
150
149
  """
151
150
  Get a list of all alert rules in the organization.
152
151
 
153
152
  :param model_id: list from the specified model
154
- :param project_id: list from the specified project
155
153
  :param metric_id: list rules set on the specified metric id
156
154
  :param columns: list rules set on the specified list of columns
157
155
  :param baseline_id: list rules set on the specified baseline_id
@@ -159,18 +157,10 @@ class AlertRule(
159
157
 
160
158
  :return: paginated list of alert rules for the specified filters
161
159
  """
162
- rules: list[QueryRule | QueryCondition] = []
160
+ rules: list[QueryRule | QueryCondition] = [
161
+ QueryRule(field='model_id', operator=OperatorType.EQUAL, value=model_id)
162
+ ]
163
163
 
164
- if model_id:
165
- rules.append(
166
- QueryRule(field='model_id', operator=OperatorType.EQUAL, value=model_id)
167
- )
168
- if project_id:
169
- rules.append(
170
- QueryRule(
171
- field='project_id', operator=OperatorType.EQUAL, value=project_id
172
- )
173
- )
174
164
  if baseline_id:
175
165
  rules.append(
176
166
  QueryRule(
@@ -22,10 +22,10 @@ class Baseline(
22
22
  def __init__( # pylint: disable=too-many-arguments
23
23
  self,
24
24
  name: str,
25
- model_id: UUID,
25
+ model_id: UUID | str,
26
26
  environment: EnvType,
27
27
  type_: str,
28
- dataset_id: UUID | None = None,
28
+ dataset_id: UUID | str | None = None,
29
29
  start_time: int | None = None,
30
30
  end_time: int | None = None,
31
31
  offset: int | None = None,
@@ -134,27 +134,23 @@ class Baseline(
134
134
 
135
135
  @classmethod
136
136
  @handle_api_error
137
- def from_name(cls, name: str, model_name: str, project_name: str) -> Baseline:
137
+ def from_name(cls, name: str, model_id: UUID | str) -> Baseline:
138
138
  """
139
- Get the baseline instance using baseline name, model name and project name.
139
+ Get the baseline instance of a model from baseline name
140
140
 
141
141
  :param name: Baseline name
142
- :param model_name: Name of the model associated with the baseline
143
- :param project_name: Name of the project associated with the baseline
142
+ :param model_id: Model identifier
144
143
 
145
- :return: Baseline instance for the provided params
144
+ :return: Baseline instance
146
145
  """
147
146
 
148
147
  _filter = QueryCondition(
149
148
  rules=[
150
149
  QueryRule(field='name', operator=OperatorType.EQUAL, value=name),
151
150
  QueryRule(
152
- field='project_name',
151
+ field='model_id',
153
152
  operator=OperatorType.EQUAL,
154
- value=project_name,
155
- ),
156
- QueryRule(
157
- field='model_name', operator=OperatorType.EQUAL, value=model_name
153
+ value=model_id,
158
154
  ),
159
155
  ]
160
156
  )
@@ -172,18 +168,14 @@ class Baseline(
172
168
  @handle_api_error
173
169
  def list(
174
170
  cls,
175
- model_id: UUID | None = None,
171
+ model_id: UUID | str,
176
172
  type_: str | None = None,
177
173
  environment: EnvType | None = None,
178
174
  ) -> Iterator[Baseline]:
179
- """Get a list of all baselines in the organization."""
175
+ """Get a list of all baselines of a model."""
180
176
 
181
177
  rules: list[QueryRule | QueryCondition] = []
182
178
 
183
- if model_id:
184
- rules.append(
185
- QueryRule(field='model_id', operator=OperatorType.EQUAL, value=model_id)
186
- )
187
179
  if type_:
188
180
  rules.append(
189
181
  QueryRule(field='type', operator=OperatorType.EQUAL, value=type_)
@@ -200,13 +192,14 @@ class Baseline(
200
192
  _filter = QueryCondition(rules=rules)
201
193
  params: dict[str, Any] = {'filter': _filter.json()}
202
194
 
203
- for baseline in cls._paginate(url=cls._get_url(), params=params):
195
+ url = f'/v3/models/{model_id}/baselines'
196
+ for baseline in cls._paginate(url=url, params=params):
204
197
  yield cls._from_dict(data=baseline)
205
198
 
206
199
  @handle_api_error
207
200
  def create(self) -> Baseline:
208
201
  """Create a new baseline."""
209
- payload = {
202
+ payload: dict[str, Any] = {
210
203
  'name': self.name,
211
204
  'model_id': self.model_id,
212
205
  'type': self.type,
@@ -7,8 +7,9 @@ from uuid import UUID
7
7
 
8
8
  from fiddler.decorators import handle_api_error
9
9
  from fiddler.entities.base import BaseEntity
10
- from fiddler.entities.model import Model
11
- from fiddler.schemas.custom_metric import (
10
+ from fiddler.entities.model import ModelCompactMixin
11
+ from fiddler.entities.project import ProjectCompactMixin
12
+ from fiddler.schemas.custom_expression import (
12
13
  CustomExpressionResp,
13
14
  CustomMetricResp,
14
15
  SegmentResp,
@@ -17,11 +18,11 @@ from fiddler.schemas.filter_query import OperatorType, QueryCondition, QueryRule
17
18
  from fiddler.utils.helpers import raise_not_found
18
19
 
19
20
 
20
- class CustomExpression(BaseEntity):
21
+ class CustomExpression(BaseEntity, ModelCompactMixin, ProjectCompactMixin):
21
22
  def __init__(
22
23
  self,
23
24
  name: str,
24
- model_id: UUID,
25
+ model_id: UUID | str,
25
26
  definition: str,
26
27
  description: str | None = None,
27
28
  ) -> None:
@@ -37,10 +38,21 @@ class CustomExpression(BaseEntity):
37
38
  # Deserialized response object
38
39
  self._resp: CustomExpressionResp | None = None
39
40
 
41
+ @classmethod
42
+ def _get_url(cls, id_: UUID | str | None = None) -> str:
43
+ """Get custom expression resource/item url."""
44
+ url = f'/v3/{cls._get_url_path()}'
45
+ return url if not id_ else f'{url}/{id_}'
46
+
40
47
  @staticmethod
41
48
  @abstractmethod
42
- def _get_url(id_: UUID | str | None = None) -> str:
43
- """Get custom expression resource/item url."""
49
+ def _get_url_path() -> str:
50
+ """Get custom expression resource path"""
51
+
52
+ @staticmethod
53
+ @abstractmethod
54
+ def _get_display_name() -> str:
55
+ """Get custom expression display name"""
44
56
 
45
57
  def _refresh(self, data: dict) -> None:
46
58
  """Refresh the fields of this instance from the given response dictionary"""
@@ -65,14 +77,11 @@ class CustomExpression(BaseEntity):
65
77
 
66
78
  # Deserialize the response
67
79
  resp_obj = CustomMetricResp(**data)
68
- model = Model.from_name(
69
- name=resp_obj.model_name, project_name=resp_obj.project_name
70
- )
71
- assert model.id
80
+
72
81
  # Initialize
73
82
  instance = cls(
74
83
  name=resp_obj.name,
75
- model_id=model.id,
84
+ model_id=resp_obj.model.id,
76
85
  definition=resp_obj.definition,
77
86
  description=resp_obj.description,
78
87
  )
@@ -103,15 +112,12 @@ class CustomExpression(BaseEntity):
103
112
 
104
113
  @classmethod
105
114
  @handle_api_error
106
- def from_name(
107
- cls, name: str, model_name: str, project_name: str
108
- ) -> CustomExpression:
115
+ def from_name(cls, name: str, model_id: UUID | str) -> CustomExpression:
109
116
  """
110
- Get the custom metric instance using custom metric name, model name and project name.
117
+ Get the custom metric instance of a model from custom metric name
111
118
 
112
119
  :param name: Custom metric name
113
- :param model_name: Name of the model associated with the custom metric
114
- :param project_name: Name of the project associated with the custom metric
120
+ :param model_id: Model identifier
115
121
 
116
122
  :return: CustomMetric instance for the provided params
117
123
  """
@@ -119,13 +125,13 @@ class CustomExpression(BaseEntity):
119
125
  _filter = QueryCondition(
120
126
  rules=[
121
127
  QueryRule(field='name', operator=OperatorType.EQUAL, value=name),
128
+ QueryRule(
129
+ field='model_id', operator=OperatorType.EQUAL, value=model_id
130
+ ),
122
131
  ]
123
132
  )
124
133
  params: dict[str, Any] = {
125
134
  'filter': _filter.json(),
126
- 'organization_name': cls.get_organization_name(),
127
- 'project_name': project_name,
128
- 'model_name': model_name,
129
135
  }
130
136
 
131
137
  response = cls._client().get(
@@ -133,7 +139,9 @@ class CustomExpression(BaseEntity):
133
139
  params=params,
134
140
  )
135
141
  if response.json()['data']['total'] == 0:
136
- raise_not_found('Custom metric not found for the given identifier')
142
+ raise_not_found(
143
+ f'{cls._get_display_name()} not found for the given identifier'
144
+ )
137
145
 
138
146
  return cls._from_dict(data=response.json()['data']['items'][0])
139
147
 
@@ -141,32 +149,21 @@ class CustomExpression(BaseEntity):
141
149
  @handle_api_error
142
150
  def list(
143
151
  cls,
144
- model_id: UUID,
152
+ model_id: UUID | str,
145
153
  ) -> Iterator[CustomExpression]:
146
154
  """Get a list of all custom metrics in the organization."""
147
155
 
148
- model = Model.get(id_=model_id)
149
- params: dict[str, Any] = {
150
- 'organization_name': cls.get_organization_name(),
151
- 'project_name': model.project.name,
152
- 'model_name': model.name,
153
- }
156
+ url = f'/v3/models/{model_id}/{cls._get_url_path()}'
154
157
 
155
- for custom_metric in cls._paginate(
156
- url=cls._get_url(),
157
- params=params,
158
- ):
159
- yield cls._from_dict(data=custom_metric)
158
+ for item in cls._paginate(url=url):
159
+ yield cls._from_dict(data=item)
160
160
 
161
161
  @handle_api_error
162
162
  def create(self) -> CustomExpression:
163
163
  """Create a new custom metric."""
164
- model = Model.get(id_=self.model_id)
165
164
  payload = {
165
+ 'model_id': self.model_id,
166
166
  'name': self.name,
167
- 'organization_name': self.get_organization_name(),
168
- 'project_name': model.project.name,
169
- 'model_name': model.name,
170
167
  'definition': self.definition,
171
168
  }
172
169
 
@@ -190,7 +187,11 @@ class CustomExpression(BaseEntity):
190
187
 
191
188
  class CustomMetric(CustomExpression):
192
189
  def __init__(
193
- self, name: str, model_id: UUID, definition: str, description: str | None = None
190
+ self,
191
+ name: str,
192
+ model_id: UUID | str,
193
+ definition: str,
194
+ description: str | None = None,
194
195
  ) -> None:
195
196
  """Construct a custom metric instance."""
196
197
  super().__init__(name, model_id, definition, description)
@@ -199,15 +200,21 @@ class CustomMetric(CustomExpression):
199
200
  self._resp: CustomMetricResp | None = None
200
201
 
201
202
  @staticmethod
202
- def _get_url(id_: UUID | str | None = None) -> str:
203
- """Get custom metric resource/item url."""
204
- url = '/v2/custom-metrics'
205
- return url if not id_ else f'{url}/{id_}'
203
+ def _get_url_path() -> str:
204
+ return 'custom-metrics'
205
+
206
+ @staticmethod
207
+ def _get_display_name() -> str:
208
+ return 'Custom metric'
206
209
 
207
210
 
208
211
  class Segment(CustomExpression):
209
212
  def __init__(
210
- self, name: str, model_id: UUID, definition: str, description: str | None = None
213
+ self,
214
+ name: str,
215
+ model_id: UUID | str,
216
+ definition: str,
217
+ description: str | None = None,
211
218
  ) -> None:
212
219
  """Construct a segment instance."""
213
220
  super().__init__(name, model_id, definition, description)
@@ -216,7 +223,9 @@ class Segment(CustomExpression):
216
223
  self._resp: SegmentResp | None = None
217
224
 
218
225
  @staticmethod
219
- def _get_url(id_: UUID | str | None = None) -> str:
220
- """Get segment resource/item url."""
221
- url = '/v2/segments'
222
- return url if not id_ else f'{url}/{id_}'
226
+ def _get_url_path() -> str:
227
+ return 'segments'
228
+
229
+ @staticmethod
230
+ def _get_display_name() -> str:
231
+ return 'Segment'
@@ -72,13 +72,12 @@ class Dataset(BaseEntity, ProjectCompactMixin):
72
72
 
73
73
  @classmethod
74
74
  @handle_api_error
75
- def from_name(cls, name: str, model_name: str, project_name: str) -> Dataset:
75
+ def from_name(cls, name: str, model_id: UUID | str) -> Dataset:
76
76
  """
77
77
  Get the dataset instance using dataset name.
78
78
 
79
79
  :param name: Dataset name
80
- :param model_name: Name of the model associated with the dataset
81
- :param project_name: name of the project associated with the dataset
80
+ :param model_id: Model identifier
82
81
 
83
82
  :return: Dataset instance for the provided params
84
83
  """
@@ -86,12 +85,9 @@ class Dataset(BaseEntity, ProjectCompactMixin):
86
85
  rules=[
87
86
  QueryRule(field='name', operator=OperatorType.EQUAL, value=name),
88
87
  QueryRule(
89
- field='project_name',
88
+ field='model_id',
90
89
  operator=OperatorType.EQUAL,
91
- value=project_name,
92
- ),
93
- QueryRule(
94
- field='model_name', operator=OperatorType.EQUAL, value=model_name
90
+ value=model_id,
95
91
  ),
96
92
  ]
97
93
  )
@@ -108,18 +104,16 @@ class Dataset(BaseEntity, ProjectCompactMixin):
108
104
 
109
105
  @classmethod
110
106
  @handle_api_error
111
- def list(cls, model_id: UUID | str | None = None) -> Iterator[Dataset]:
107
+ def list(cls, model_id: UUID | str) -> Iterator[Dataset]:
112
108
  """
113
- Get a list of all datasets in the organization.
109
+ Get a list of all datasets of a model.
114
110
 
115
111
  :param model_id: unique uuid format identifier for model
116
112
  :return: Iterator of datasets
117
113
  """
118
114
  params: dict[str, Any] = {'type': EnvType.PRE_PRODUCTION.value}
119
- if model_id:
120
- params['model_id'] = str(model_id)
121
-
122
- for dataset in cls._paginate(url=cls._get_url(), params=params):
115
+ url = f'/v3/models/{model_id}/environments'
116
+ for dataset in cls._paginate(url=url, params=params):
123
117
  yield cls._from_dict(data=dataset)
124
118
 
125
119
 
@@ -65,7 +65,6 @@ class File(BaseEntity, CreatedByMixin, UpdatedByMixin):
65
65
  chunk_size: int = MULTI_PART_CHUNK_SIZE,
66
66
  ) -> File:
67
67
  """Upload file. Single or multipart upload depends on file size"""
68
- print(f'file size = {os.path.getsize(self.path)}, chunk_size = {chunk_size}')
69
68
  if os.path.getsize(self.path) < chunk_size:
70
69
  return self.single_upload()
71
70
 
@@ -74,14 +73,12 @@ class File(BaseEntity, CreatedByMixin, UpdatedByMixin):
74
73
  @handle_api_error
75
74
  def single_upload(self) -> File:
76
75
  """Single part file upload"""
77
- with open(self.path, 'rb') as f:
78
- response = self._client().post(
79
- url='/v3/files/upload',
80
- files={
81
- 'file': (self.name, io.BytesIO(f.read())),
82
- },
83
- headers={CONTENT_TYPE_HEADER_KEY: None},
84
- )
76
+
77
+ response = self._client().post(
78
+ url='/v3/files/upload',
79
+ files={'file': (self.name, open(self.path, 'rb'))},
80
+ headers={CONTENT_TYPE_HEADER_KEY: None},
81
+ )
85
82
 
86
83
  self._refresh_from_response(response)
87
84
  return self
@@ -49,7 +49,7 @@ class Model(
49
49
  def __init__( # pylint: disable=too-many-arguments
50
50
  self,
51
51
  name: str,
52
- project_id: UUID,
52
+ project_id: UUID | str,
53
53
  schema: ModelSchema,
54
54
  spec: ModelSpec,
55
55
  input_type: str = ModelInputType.TABULAR,
@@ -188,15 +188,21 @@ class Model(
188
188
 
189
189
  @classmethod
190
190
  @handle_api_error
191
- def from_name(cls, name: str, project_name: str) -> Model:
192
- """Get the model instance using model name and project name."""
191
+ def from_name(cls, name: str, project_id: UUID | str) -> Model:
192
+ """
193
+ Get the model instance from model name within a project.
194
+
195
+ :param name: Model name
196
+ :param project_id: Project identifier
197
+ :return: Model instance
198
+ """
193
199
  _filter = QueryCondition(
194
200
  rules=[
195
201
  QueryRule(field='name', operator=OperatorType.EQUAL, value=name),
196
202
  QueryRule(
197
- field='project_name',
203
+ field='project_id',
198
204
  operator=OperatorType.EQUAL,
199
- value=project_name,
205
+ value=project_id,
200
206
  ),
201
207
  ]
202
208
  )
@@ -251,7 +257,7 @@ class Model(
251
257
  @handle_api_error
252
258
  def list(
253
259
  cls,
254
- project_id: UUID | None = None,
260
+ project_id: UUID | str,
255
261
  ) -> Iterator[ModelCompact]:
256
262
  """
257
263
  Get a list of all models with the given filters
@@ -259,9 +265,15 @@ class Model(
259
265
  :param project_id: Project identifier
260
266
  :return: ModelCompact iterator
261
267
  """
262
- params = {}
263
- if project_id:
264
- params['project_id'] = project_id
268
+ _filter = QueryCondition(
269
+ rules=[
270
+ QueryRule(
271
+ field='project_id', operator=OperatorType.EQUAL, value=project_id
272
+ ),
273
+ ]
274
+ )
275
+
276
+ params = {'filter': _filter.json()}
265
277
 
266
278
  for model in cls._paginate(url=cls._get_url(), params=params):
267
279
  yield ModelCompact(id=model['id'], name=model['name'])
@@ -273,6 +285,8 @@ class Model(
273
285
  Dataset,
274
286
  )
275
287
 
288
+ assert self.id is not None
289
+
276
290
  yield from Dataset.list(model_id=self.id)
277
291
 
278
292
  @property
@@ -282,6 +296,8 @@ class Model(
282
296
  Baseline,
283
297
  )
284
298
 
299
+ assert self.id is not None
300
+
285
301
  yield from Baseline.list(model_id=self.id)
286
302
 
287
303
  @cached_property
@@ -298,7 +314,7 @@ class Model(
298
314
  cls,
299
315
  source: pd.DataFrame | Path | str,
300
316
  name: str,
301
- project_id: UUID,
317
+ project_id: UUID | str,
302
318
  spec: ModelSpec | None = None,
303
319
  input_type: str = ModelInputType.TABULAR,
304
320
  task: str = ModelTask.NOT_SET,
@@ -442,7 +458,7 @@ class Model(
442
458
 
443
459
  def add_surrogate(
444
460
  self,
445
- dataset_id: UUID,
461
+ dataset_id: UUID | str,
446
462
  deployment_params: DeploymentParams | None = None,
447
463
  ) -> Job:
448
464
  """
@@ -460,7 +476,7 @@ class Model(
460
476
  @handle_api_error
461
477
  def update_surrogate(
462
478
  self,
463
- dataset_id: UUID,
479
+ dataset_id: UUID | str,
464
480
  deployment_params: DeploymentParams | None = None,
465
481
  ) -> Job:
466
482
  """
@@ -93,7 +93,7 @@ class ModelArtifact(ConnectionMixin):
93
93
 
94
94
  def _artifact_deploy(
95
95
  self,
96
- file_id: UUID,
96
+ file_id: UUID | str,
97
97
  deployment_params: DeploymentParams | None = None,
98
98
  update: bool = False,
99
99
  ) -> Job:
@@ -18,7 +18,7 @@ class ModelDeployment(
18
18
  ): # pylint: disable=too-many-instance-attributes
19
19
  def __init__( # pylint: disable=too-many-arguments
20
20
  self,
21
- model_id: UUID,
21
+ model_id: UUID | str,
22
22
  ) -> None:
23
23
  """Construct a model deployment instance."""
24
24
  self.id: UUID | None = None # pylint: disable=invalid-name
@@ -124,6 +124,8 @@ class Project(BaseEntity):
124
124
  Model,
125
125
  )
126
126
 
127
+ assert self.id is not None
128
+
127
129
  yield from Model.list(project_id=self.id)
128
130
 
129
131
 
@@ -25,7 +25,7 @@ class Surrogate(ConnectionMixin):
25
25
 
26
26
  def _deploy(
27
27
  self,
28
- dataset_id: UUID,
28
+ dataset_id: UUID | str,
29
29
  deployment_params: DeploymentParams | None = None,
30
30
  update: bool = False,
31
31
  ) -> Job:
@@ -71,7 +71,7 @@ class Surrogate(ConnectionMixin):
71
71
  @handle_api_error
72
72
  def add(
73
73
  self,
74
- dataset_id: UUID,
74
+ dataset_id: UUID | str,
75
75
  deployment_params: DeploymentParams | None = None,
76
76
  ) -> Job:
77
77
  """
@@ -89,7 +89,7 @@ class Surrogate(ConnectionMixin):
89
89
  @handle_api_error
90
90
  def update(
91
91
  self,
92
- dataset_id: UUID,
92
+ dataset_id: UUID | str,
93
93
  deployment_params: DeploymentParams | None = None,
94
94
  ) -> Job:
95
95
  """
@@ -382,7 +382,7 @@ class XaiMixin:
382
382
  @handle_api_error
383
383
  def precompute_feature_impact( # pylint: disable=too-many-arguments
384
384
  self,
385
- dataset_id: UUID,
385
+ dataset_id: UUID | str,
386
386
  num_samples: int | None = None,
387
387
  num_iterations: int | None = None,
388
388
  num_refs: int | None = None,
@@ -444,7 +444,7 @@ class XaiMixin:
444
444
  @handle_api_error
445
445
  def precompute_feature_importance( # pylint: disable=too-many-arguments
446
446
  self,
447
- dataset_id: UUID,
447
+ dataset_id: UUID | str,
448
448
  num_samples: int | None = None,
449
449
  num_iterations: int | None = None,
450
450
  num_refs: int | None = None,
@@ -528,7 +528,7 @@ class XaiMixin:
528
528
  @handle_api_error
529
529
  def precompute_predictions(
530
530
  self,
531
- dataset_id: UUID,
531
+ dataset_id: UUID | str,
532
532
  chunk_size: int | None = None,
533
533
  update: bool = False,
534
534
  ) -> Job: