fiddler-client 3.1.0.dev2__tar.gz → 3.1.0.dev3__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.
- {fiddler-client-3.1.0.dev2/fiddler_client.egg-info → fiddler-client-3.1.0.dev3}/PKG-INFO +2 -1
- fiddler-client-3.1.0.dev3/fiddler/VERSION +1 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/__init__.py +2 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/alert_rule.py +5 -1
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/events.py +51 -16
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/model.py +23 -10
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/webhook.py +18 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/alert_rule.py +3 -2
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/custom_expression.py +7 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_alert_rule.py +44 -37
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_model.py +7 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_webhook.py +57 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3/fiddler_client.egg-info}/PKG-INFO +2 -1
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler_client.egg-info/requires.txt +1 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/setup.py +1 -0
- fiddler-client-3.1.0.dev2/fiddler/VERSION +0 -1
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/LICENSE.txt +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/MANIFEST.in +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/PUBLIC.md +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/README.md +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/configs.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/connection.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/__init__.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/alert_rule.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/baseline.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/common.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/dataset.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/events.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/job.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/model.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/model_deployment.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/xai.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/decorators.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/__init__.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/alert_record.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/base.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/baseline.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/custom_expression.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/dataset.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/file.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/job.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/model_artifact.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/model_deployment.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/organization.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/project.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/surrogate.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/user.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/xai.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/exceptions.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/libs/__init__.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/libs/http_client.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/libs/json_encoder.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/libs/semver.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/packtools/__init__.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/packtools/gem.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/packtools/keras_ig_helpers.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/packtools/project_attributions_helpers.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/packtools/template_model.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/__init__.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/alert_record.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/base.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/baseline.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/custom_features.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/dataset.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/events.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/file.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/filter_query.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/job.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/model.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/model_deployment.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/model_schema.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/model_spec.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/model_task_params.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/organization.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/project.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/response.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/server_info.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/user.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/webhook.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/xai.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/xai_params.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/__init__.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/__init__.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_alert_record.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_baseline.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_custom_metric.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_dataset.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_events.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_files.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_generate_model.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_job.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_mixin.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_model_artifact.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_model_deployment.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_model_surrogate.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_project.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_segment.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_xai.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/conftest.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/constants.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/test_connection.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/test_json_encoder.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/test_logger.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/test_utils.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/utils.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/utils/__init__.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/utils/helpers.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/utils/logger.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/utils/model_generator.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/utils/validations.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/utils/version.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/version.py +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler_client.egg-info/SOURCES.txt +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler_client.egg-info/dependency_links.txt +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler_client.egg-info/top_level.txt +0 -0
- {fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fiddler-client
|
|
3
|
-
Version: 3.1.0.
|
|
3
|
+
Version: 3.1.0.dev3
|
|
4
4
|
Summary: Python client for Fiddler Platform
|
|
5
5
|
Home-page: https://fiddler.ai
|
|
6
6
|
Author: Fiddler Labs
|
|
@@ -20,6 +20,7 @@ Requires-Dist: tqdm
|
|
|
20
20
|
Requires-Dist: simplejson>=3.17.0
|
|
21
21
|
Requires-Dist: pyarrow>=7.0.0
|
|
22
22
|
Requires-Dist: pyyaml
|
|
23
|
+
Requires-Dist: typing-extensions<=4.5.0
|
|
23
24
|
|
|
24
25
|
Fiddler Client
|
|
25
26
|
=============
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.1.0.dev3
|
|
@@ -61,6 +61,7 @@ from fiddler.schemas.xai import ( # noqa
|
|
|
61
61
|
SqlSliceQueryDataSource,
|
|
62
62
|
)
|
|
63
63
|
from fiddler.schemas.xai_params import XaiParams # noqa
|
|
64
|
+
from fiddler.utils.helpers import group_by # noqa
|
|
64
65
|
from fiddler.utils.logger import set_logging # noqa
|
|
65
66
|
from fiddler.version import __version__ # noqa
|
|
66
67
|
|
|
@@ -141,4 +142,5 @@ __all__ = [
|
|
|
141
142
|
'ApiError',
|
|
142
143
|
# Utilities
|
|
143
144
|
'set_logging',
|
|
145
|
+
'group_by',
|
|
144
146
|
]
|
|
@@ -34,6 +34,7 @@ class AlertRule(
|
|
|
34
34
|
warning_threshold: float | None = None,
|
|
35
35
|
columns: list[str] | None = None,
|
|
36
36
|
baseline_id: UUID | str | None = None,
|
|
37
|
+
segment_id: UUID | str | None = None,
|
|
37
38
|
compare_bin_delta: int | None = None,
|
|
38
39
|
) -> None:
|
|
39
40
|
"""Construct a alert rule instance."""
|
|
@@ -49,6 +50,7 @@ class AlertRule(
|
|
|
49
50
|
self.critical_threshold = critical_threshold
|
|
50
51
|
self.condition = condition
|
|
51
52
|
self.bin_size = bin_size
|
|
53
|
+
self.segment_id = segment_id
|
|
52
54
|
|
|
53
55
|
self.id: UUID | None = None
|
|
54
56
|
self.project_id: UUID | None = None
|
|
@@ -84,7 +86,8 @@ class AlertRule(
|
|
|
84
86
|
critical_threshold=resp_obj.critical_threshold,
|
|
85
87
|
warning_threshold=resp_obj.warning_threshold,
|
|
86
88
|
columns=resp_obj.columns,
|
|
87
|
-
baseline_id=resp_obj.
|
|
89
|
+
baseline_id=resp_obj.baseline.id if resp_obj.baseline else None,
|
|
90
|
+
segment_id=resp_obj.segment.id if resp_obj.segment else None,
|
|
88
91
|
compare_bin_delta=resp_obj.compare_bin_delta,
|
|
89
92
|
)
|
|
90
93
|
|
|
@@ -210,6 +213,7 @@ class AlertRule(
|
|
|
210
213
|
'compare_to': self.compare_to,
|
|
211
214
|
'condition': self.condition,
|
|
212
215
|
'bin_size': self.bin_size,
|
|
216
|
+
'segment_id': self.segment_id,
|
|
213
217
|
'critical_threshold': self.critical_threshold,
|
|
214
218
|
'warning_threshold': self.warning_threshold,
|
|
215
219
|
'feature_names': self.columns,
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import tempfile
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any, Callable
|
|
6
6
|
from uuid import UUID
|
|
7
7
|
|
|
8
8
|
import pandas as pd
|
|
@@ -17,6 +17,9 @@ from fiddler.entities.job import Job
|
|
|
17
17
|
from fiddler.schemas.dataset import EnvType
|
|
18
18
|
from fiddler.schemas.events import EventsSource, FileSource
|
|
19
19
|
from fiddler.schemas.job import JobCompactResp
|
|
20
|
+
from fiddler.utils.logger import get_logger
|
|
21
|
+
|
|
22
|
+
logger = get_logger(__name__)
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
class EventPublisher(ConnectionMixin):
|
|
@@ -51,40 +54,72 @@ class EventPublisher(ConnectionMixin):
|
|
|
51
54
|
|
|
52
55
|
:return: list[UUID] for list of dicts source and Job object for file path or dataframe source.
|
|
53
56
|
"""
|
|
57
|
+
|
|
58
|
+
publish_method = self._get_publish_method(source=source)
|
|
59
|
+
|
|
60
|
+
return publish_method(
|
|
61
|
+
source=source,
|
|
62
|
+
environment=environment,
|
|
63
|
+
dataset_name=dataset_name,
|
|
64
|
+
update=update,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def _get_publish_method(
|
|
68
|
+
self, source: list[dict[str, Any]] | str | Path | pd.DataFrame
|
|
69
|
+
) -> Callable:
|
|
54
70
|
if isinstance(source, (str, Path)):
|
|
55
|
-
return self._publish_file
|
|
56
|
-
source=source,
|
|
57
|
-
environment=environment,
|
|
58
|
-
dataset_name=dataset_name,
|
|
59
|
-
update=update,
|
|
60
|
-
)
|
|
71
|
+
return self._publish_file
|
|
61
72
|
|
|
62
73
|
if isinstance(source, pd.DataFrame):
|
|
63
|
-
|
|
64
|
-
|
|
74
|
+
return self._publish_df
|
|
75
|
+
|
|
76
|
+
if isinstance(source, list):
|
|
77
|
+
return self._publish_stream
|
|
78
|
+
|
|
79
|
+
raise ValueError(f'Unsupported source - {type(source)}')
|
|
80
|
+
|
|
81
|
+
def _publish_df(
|
|
82
|
+
self,
|
|
83
|
+
source: pd.DataFrame,
|
|
84
|
+
environment: EnvType,
|
|
85
|
+
dataset_name: str | None = None,
|
|
86
|
+
update: bool = False,
|
|
87
|
+
) -> Job:
|
|
88
|
+
with tempfile.NamedTemporaryFile(suffix='.parquet') as temp_file:
|
|
89
|
+
try:
|
|
90
|
+
source.to_parquet(temp_file.name, index=False)
|
|
65
91
|
return self._publish_file(
|
|
66
92
|
source=temp_file.name,
|
|
67
93
|
environment=environment,
|
|
68
94
|
dataset_name=dataset_name,
|
|
69
95
|
update=update,
|
|
70
96
|
)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
97
|
+
except Exception:
|
|
98
|
+
logger.warning(
|
|
99
|
+
'Failed to convert input dataframe to parquet format. Retrying as a CSV file.'
|
|
100
|
+
)
|
|
101
|
+
with tempfile.NamedTemporaryFile(suffix='.csv') as temp_file:
|
|
102
|
+
source.to_csv(temp_file.name, index=False)
|
|
103
|
+
return self._publish_file(
|
|
104
|
+
source=temp_file.name,
|
|
105
|
+
environment=environment,
|
|
106
|
+
dataset_name=dataset_name,
|
|
107
|
+
update=update,
|
|
108
|
+
)
|
|
76
109
|
|
|
77
110
|
def _publish_stream(
|
|
78
111
|
self,
|
|
79
112
|
source: list[dict[str, Any]],
|
|
113
|
+
environment: EnvType = EnvType.PRODUCTION,
|
|
114
|
+
dataset_name: str | None = None,
|
|
80
115
|
update: bool = False,
|
|
81
116
|
) -> list[UUID]:
|
|
82
117
|
event_ids = []
|
|
83
118
|
for i in tqdm(range(0, len(source), self.STREAM_LIMIT)):
|
|
84
119
|
response = self._publish_call(
|
|
85
120
|
source=EventsSource(events=source[i : i + self.STREAM_LIMIT]),
|
|
86
|
-
environment=
|
|
87
|
-
dataset_name=
|
|
121
|
+
environment=environment,
|
|
122
|
+
dataset_name=dataset_name,
|
|
88
123
|
update=update,
|
|
89
124
|
)
|
|
90
125
|
event_ids.extend(response.json()['data']['event_ids'])
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import builtins
|
|
4
|
-
import copy
|
|
5
4
|
import typing
|
|
6
5
|
from dataclasses import dataclass
|
|
7
6
|
from datetime import datetime
|
|
@@ -33,6 +32,7 @@ from fiddler.schemas.model_spec import ModelSpec
|
|
|
33
32
|
from fiddler.schemas.model_task_params import ModelTaskParams
|
|
34
33
|
from fiddler.schemas.xai_params import XaiParams
|
|
35
34
|
from fiddler.utils.helpers import raise_not_found
|
|
35
|
+
from fiddler.utils.logger import get_logger
|
|
36
36
|
from fiddler.utils.model_generator import ModelGenerator
|
|
37
37
|
|
|
38
38
|
if typing.TYPE_CHECKING:
|
|
@@ -40,6 +40,9 @@ if typing.TYPE_CHECKING:
|
|
|
40
40
|
from fiddler.entities.dataset import Dataset
|
|
41
41
|
|
|
42
42
|
|
|
43
|
+
logger = get_logger(__name__)
|
|
44
|
+
|
|
45
|
+
|
|
43
46
|
class Model(
|
|
44
47
|
BaseEntity,
|
|
45
48
|
CreatedByMixin,
|
|
@@ -307,7 +310,9 @@ class Model(
|
|
|
307
310
|
params = {'filter': _filter.json()}
|
|
308
311
|
|
|
309
312
|
for model in cls._paginate(url=cls._get_url(), params=params):
|
|
310
|
-
yield ModelCompact(
|
|
313
|
+
yield ModelCompact(
|
|
314
|
+
id=model['id'], name=model['name'], version=model['version']
|
|
315
|
+
)
|
|
311
316
|
|
|
312
317
|
def duplicate(self, version: str | None = None) -> Model:
|
|
313
318
|
"""
|
|
@@ -319,13 +324,21 @@ class Model(
|
|
|
319
324
|
:param version: Version name for the new instance
|
|
320
325
|
:return: Model instance
|
|
321
326
|
"""
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
return Model(
|
|
328
|
+
name=self.name,
|
|
329
|
+
project_id=self.project_id,
|
|
330
|
+
schema=self.schema,
|
|
331
|
+
spec=self.spec,
|
|
332
|
+
version=version if version else self.version,
|
|
333
|
+
input_type=self.input_type,
|
|
334
|
+
task=self.task,
|
|
335
|
+
task_params=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=self.xai_params,
|
|
341
|
+
)
|
|
329
342
|
|
|
330
343
|
@property
|
|
331
344
|
def datasets(self) -> Iterator[Dataset]:
|
|
@@ -456,7 +469,7 @@ class Model(
|
|
|
456
469
|
:return: list[UUID] for list of dicts or dataframe source and Job object for
|
|
457
470
|
file path source.
|
|
458
471
|
"""
|
|
459
|
-
|
|
472
|
+
logger.info('Model[%s/%s] - Publishing events', self.name, self.version)
|
|
460
473
|
return self._event_publisher.publish(
|
|
461
474
|
source=source,
|
|
462
475
|
environment=environment,
|
|
@@ -6,7 +6,9 @@ from uuid import UUID
|
|
|
6
6
|
|
|
7
7
|
from fiddler.decorators import handle_api_error
|
|
8
8
|
from fiddler.entities.base import BaseEntity
|
|
9
|
+
from fiddler.schemas.filter_query import OperatorType, QueryCondition, QueryRule
|
|
9
10
|
from fiddler.schemas.webhook import WebhookProvider, WebhookResp
|
|
11
|
+
from fiddler.utils.helpers import raise_not_found
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class Webhook(BaseEntity):
|
|
@@ -81,6 +83,22 @@ class Webhook(BaseEntity):
|
|
|
81
83
|
response = cls._client().get(url=cls._get_url(id_))
|
|
82
84
|
return cls._from_response(response=response)
|
|
83
85
|
|
|
86
|
+
@classmethod
|
|
87
|
+
@handle_api_error
|
|
88
|
+
def from_name(cls, name: str) -> Webhook:
|
|
89
|
+
"""Get the webhook instance using webhook name"""
|
|
90
|
+
_filter = QueryCondition(
|
|
91
|
+
rules=[QueryRule(field='name', operator=OperatorType.EQUAL, value=name)]
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
response = cls._client().get(
|
|
95
|
+
url=cls._get_url(), params={'filter': _filter.json()}
|
|
96
|
+
)
|
|
97
|
+
if response.json()['data']['total'] == 0:
|
|
98
|
+
raise_not_found('Webhook not found for the given identifier')
|
|
99
|
+
|
|
100
|
+
return cls._from_dict(data=response.json()['data']['items'][0])
|
|
101
|
+
|
|
84
102
|
@classmethod
|
|
85
103
|
@handle_api_error
|
|
86
104
|
def list(cls) -> Iterator[Webhook]:
|
|
@@ -7,6 +7,7 @@ from pydantic import Field
|
|
|
7
7
|
from fiddler.constants.alert_rule import AlertCondition, BinSize, CompareTo, Priority
|
|
8
8
|
from fiddler.schemas.base import BaseModel
|
|
9
9
|
from fiddler.schemas.baseline import BaselineCompactResp
|
|
10
|
+
from fiddler.schemas.custom_expression import SegmentCompactResp
|
|
10
11
|
from fiddler.schemas.model import ModelCompactResp
|
|
11
12
|
from fiddler.schemas.project import ProjectCompactResp
|
|
12
13
|
|
|
@@ -17,14 +18,14 @@ class AlertRuleResp(BaseModel):
|
|
|
17
18
|
model: ModelCompactResp
|
|
18
19
|
project: ProjectCompactResp
|
|
19
20
|
baseline: Optional[BaselineCompactResp]
|
|
21
|
+
segment: Optional[SegmentCompactResp]
|
|
20
22
|
priority: Union[str, Priority]
|
|
21
23
|
compare_to: Union[str, CompareTo]
|
|
22
24
|
metric_id: Union[str, UUID]
|
|
23
25
|
critical_threshold: float
|
|
24
26
|
condition: Union[str, AlertCondition]
|
|
25
27
|
bin_size: Union[str, BinSize]
|
|
26
|
-
columns: Optional[List[str]]
|
|
27
|
-
baseline_id: Optional[UUID]
|
|
28
|
+
columns: Optional[List[str]] = Field(alias='feature_names')
|
|
28
29
|
compare_bin_delta: Optional[int]
|
|
29
30
|
warning_threshold: Optional[float]
|
|
30
31
|
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_alert_rule.py
RENAMED
|
@@ -28,54 +28,61 @@ from fiddler.utils.logger import set_logging
|
|
|
28
28
|
|
|
29
29
|
API_RESPONSE_200 = {
|
|
30
30
|
'data': {
|
|
31
|
-
'
|
|
32
|
-
'id': 620,
|
|
33
|
-
'created_at': '2023-11-28T08:04:12.651937+00:00',
|
|
31
|
+
'id': 794,
|
|
34
32
|
'organization_name': 'mainbuild',
|
|
35
|
-
'
|
|
36
|
-
'
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
41
|
-
'
|
|
42
|
-
'
|
|
33
|
+
'project_name': PROJECT_NAME,
|
|
34
|
+
'model_id': 285,
|
|
35
|
+
'name': 'test_rule',
|
|
36
|
+
'metric': 'jsd',
|
|
37
|
+
'metric_id': 'jsd',
|
|
38
|
+
'metric_display_name': 'Jensen-Shannon Distance',
|
|
39
|
+
'alert_type': 'drift',
|
|
40
|
+
'alert_type_display_name': 'Data Drift',
|
|
41
|
+
'priority': 'MEDIUM',
|
|
43
42
|
'baseline_name': BASELINE_NAME,
|
|
44
|
-
'
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
'feature_names': ['creditscore'],
|
|
44
|
+
'time_bucket': 3600000,
|
|
45
|
+
'category': None,
|
|
46
|
+
'bin_size': 'Hour',
|
|
47
|
+
'compare_to': 'raw_value',
|
|
48
48
|
'condition': 'greater',
|
|
49
|
-
'
|
|
50
|
-
'
|
|
51
|
-
'
|
|
52
|
-
'name': 'Age Missing 1 Hr',
|
|
53
|
-
'model_name': MODEL_NAME,
|
|
54
|
-
'model': {
|
|
55
|
-
'id': MODEL_ID,
|
|
56
|
-
'name': MODEL_NAME,
|
|
57
|
-
},
|
|
49
|
+
'compare_period': None,
|
|
50
|
+
'warning_threshold': 1.0,
|
|
51
|
+
'critical_threshold': 2.3,
|
|
58
52
|
'is_active': True,
|
|
59
53
|
'created_by': 'admin@fiddler.ai',
|
|
60
|
-
'
|
|
61
|
-
'
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
|
|
65
|
-
'
|
|
54
|
+
'created_at': '2024-04-23T10:34:14.321895+00:00',
|
|
55
|
+
'last_updated': '2024-04-23T10:34:14.323554+00:00',
|
|
56
|
+
'model_name': 'bank_churn',
|
|
57
|
+
'enable_notification': True,
|
|
58
|
+
'segment': {
|
|
59
|
+
'id': '1c9b551a-808b-4ef0-b67b-e788eaf1e6de',
|
|
60
|
+
'organization_name': 'mainbuild',
|
|
61
|
+
'project_name': 'nick_test_project_11',
|
|
62
|
+
'model_name': 'bank_churn',
|
|
63
|
+
'name': 'xyzab',
|
|
64
|
+
'definition': 'Age > 10',
|
|
65
|
+
'description': 'meh',
|
|
66
|
+
'created_at': '2024-04-23T10:31:52.181550+00:00',
|
|
67
|
+
'created_by': {
|
|
68
|
+
'id': 1,
|
|
69
|
+
'full_name': 'Fiddler Administrator',
|
|
70
|
+
'email': 'admin@fiddler.ai',
|
|
71
|
+
},
|
|
66
72
|
},
|
|
67
|
-
'
|
|
68
|
-
'
|
|
69
|
-
'
|
|
70
|
-
'
|
|
73
|
+
'project': {'id': PROJECT_ID, 'name': PROJECT_NAME},
|
|
74
|
+
'model': {'id': MODEL_ID, 'name': MODEL_NAME, 'version': 'v1'},
|
|
75
|
+
'baseline': {'id': BASELINE_ID, 'name': BASELINE_NAME},
|
|
76
|
+
'compare_bin_delta': None,
|
|
77
|
+
'uuid': ALERT_RULE_ID,
|
|
71
78
|
'notifications': {
|
|
72
|
-
'emails': {'alert_config_uuid': ALERT_RULE_ID, 'email': 'admin@fiddler.ai'},
|
|
73
79
|
'pagerduty': {
|
|
74
|
-
'severity': '',
|
|
75
80
|
'alert_config_uuid': ALERT_RULE_ID,
|
|
76
81
|
'service': '',
|
|
82
|
+
'severity': '',
|
|
77
83
|
},
|
|
78
|
-
'
|
|
84
|
+
'emails': {'email': ''},
|
|
85
|
+
'webhooks': [],
|
|
79
86
|
},
|
|
80
87
|
},
|
|
81
88
|
'api_version': '2.0',
|
|
@@ -471,6 +471,7 @@ def test_model_list_success() -> None:
|
|
|
471
471
|
models = Model.list(project_id=PROJECT_ID)
|
|
472
472
|
for model in models:
|
|
473
473
|
assert isinstance(model, ModelCompact)
|
|
474
|
+
assert model.version is not None
|
|
474
475
|
|
|
475
476
|
|
|
476
477
|
@responses.activate
|
|
@@ -654,12 +655,18 @@ def test_model_duplicate() -> None:
|
|
|
654
655
|
model = Model.get(id_=MODEL_ID)
|
|
655
656
|
|
|
656
657
|
assert model.id == UUID(MODEL_ID)
|
|
658
|
+
assert model._event_publisher.model_id == model.id
|
|
657
659
|
|
|
658
660
|
# Without version parameter
|
|
659
661
|
model_copy = model.duplicate()
|
|
662
|
+
|
|
660
663
|
assert model_copy.id is None
|
|
661
664
|
assert model_copy.version == model.version
|
|
662
665
|
|
|
666
|
+
with pytest.raises(AssertionError):
|
|
667
|
+
# since id is None
|
|
668
|
+
_ = model_copy._event_publisher
|
|
669
|
+
|
|
663
670
|
# With version parameter
|
|
664
671
|
new_version = 'v2'
|
|
665
672
|
model_copy = model.duplicate(version=new_version)
|
|
@@ -48,6 +48,29 @@ API_RESPONSE_404 = {
|
|
|
48
48
|
'kind': 'ERROR',
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
API_RESPONSE_FROM_NAME = {
|
|
52
|
+
'data': {
|
|
53
|
+
'page_size': 100,
|
|
54
|
+
'total': 1,
|
|
55
|
+
'item_count': 1,
|
|
56
|
+
'page_count': 1,
|
|
57
|
+
'page_index': 1,
|
|
58
|
+
'offset': 0,
|
|
59
|
+
'items': [
|
|
60
|
+
{
|
|
61
|
+
'id': 1,
|
|
62
|
+
'uuid': WEBHOOK_ID,
|
|
63
|
+
'name': WEBHOOK_NAME,
|
|
64
|
+
'url': WEBHOOK_URL,
|
|
65
|
+
'provider': WEBHOOK_PROVIDER,
|
|
66
|
+
'created_at': '2024-04-30T13:38:08.408013+00:00',
|
|
67
|
+
'updated_at': '2024-04-30T13:38:08.408013+00:00',
|
|
68
|
+
'organization_name': ORG_NAME,
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
51
74
|
LIST_API_RESPONSE = {
|
|
52
75
|
'data': {
|
|
53
76
|
'page_size': 100,
|
|
@@ -124,6 +147,40 @@ def test_get_webhook_not_found() -> None:
|
|
|
124
147
|
Webhook.get(id_=webhook_id)
|
|
125
148
|
|
|
126
149
|
|
|
150
|
+
@responses.activate
|
|
151
|
+
def test_webhook_from_name_success() -> None:
|
|
152
|
+
params = {
|
|
153
|
+
'filter': '{"condition": "AND", "rules": [{"field": "name", "operator": "equal", "value": "test_webhook_config_name"}]}'
|
|
154
|
+
}
|
|
155
|
+
responses.get(
|
|
156
|
+
url=f'{URL}/v2/webhooks',
|
|
157
|
+
json=API_RESPONSE_FROM_NAME,
|
|
158
|
+
match=[responses.matchers.query_param_matcher(params)],
|
|
159
|
+
)
|
|
160
|
+
webhook = Webhook.from_name(name=WEBHOOK_NAME)
|
|
161
|
+
assert isinstance(webhook, Webhook)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@responses.activate
|
|
165
|
+
def test_webhook_from_name_not_found() -> None:
|
|
166
|
+
resp = API_RESPONSE_FROM_NAME.copy()
|
|
167
|
+
resp['data']['total'] = 0
|
|
168
|
+
resp['data']['item_count'] = 0
|
|
169
|
+
resp['data']['items'] = []
|
|
170
|
+
|
|
171
|
+
params = {
|
|
172
|
+
'filter': '{"condition": "AND", "rules": [{"field": "name", "operator": "equal", "value": "test_webhook_config_name"}]}'
|
|
173
|
+
}
|
|
174
|
+
responses.get(
|
|
175
|
+
url=f'{URL}/v2/webhooks',
|
|
176
|
+
json=resp,
|
|
177
|
+
match=[responses.matchers.query_param_matcher(params)],
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
with pytest.raises(NotFound):
|
|
181
|
+
Webhook.from_name(name=WEBHOOK_NAME)
|
|
182
|
+
|
|
183
|
+
|
|
127
184
|
@responses.activate
|
|
128
185
|
def test_webhook_list_success() -> None:
|
|
129
186
|
responses.get(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fiddler-client
|
|
3
|
-
Version: 3.1.0.
|
|
3
|
+
Version: 3.1.0.dev3
|
|
4
4
|
Summary: Python client for Fiddler Platform
|
|
5
5
|
Home-page: https://fiddler.ai
|
|
6
6
|
Author: Fiddler Labs
|
|
@@ -20,6 +20,7 @@ Requires-Dist: tqdm
|
|
|
20
20
|
Requires-Dist: simplejson>=3.17.0
|
|
21
21
|
Requires-Dist: pyarrow>=7.0.0
|
|
22
22
|
Requires-Dist: pyyaml
|
|
23
|
+
Requires-Dist: typing-extensions<=4.5.0
|
|
23
24
|
|
|
24
25
|
Fiddler Client
|
|
25
26
|
=============
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
3.1.0.dev2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/constants/model_deployment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/custom_expression.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/entities/model_deployment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/packtools/keras_ig_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/schemas/model_task_params.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_alert_record.py
RENAMED
|
File without changes
|
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_custom_metric.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_generate_model.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_model_artifact.py
RENAMED
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_model_deployment.py
RENAMED
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler/tests/apis/test_model_surrogate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler_client.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{fiddler-client-3.1.0.dev2 → fiddler-client-3.1.0.dev3}/fiddler_client.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|