fiddler-client 3.4.0.dev1__tar.gz → 3.5.0.dev1__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.4.0.dev1/fiddler_client.egg-info → fiddler_client-3.5.0.dev1}/PKG-INFO +2 -2
- fiddler_client-3.5.0.dev1/fiddler/VERSION +1 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/__init__.py +2 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/connection.py +6 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/common.py +2 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/xai.py +9 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/alert_rule.py +2 -2
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/xai.py +99 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/exceptions.py +2 -2
- fiddler_client-3.5.0.dev1/fiddler/libs/aws.py +95 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/libs/http_client.py +22 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/packtools/project_attributions_helpers.py +10 -8
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/alert_record.py +1 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/alert_rule.py +1 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/base.py +2 -2
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/baseline.py +1 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/custom_features.py +1 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/file.py +1 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/model_schema.py +1 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/model_spec.py +11 -5
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/user.py +1 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/xai.py +1 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/xai_params.py +1 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_alert_rule.py +110 -10
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_model.py +11 -5
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_webhook.py +6 -6
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_xai.py +30 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/constants.py +3 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/test_connection.py +11 -1
- fiddler_client-3.5.0.dev1/fiddler/tests/test_sagemaker_auth.py +75 -0
- fiddler_client-3.5.0.dev1/fiddler/utils/decorators.py +48 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/logger.py +7 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1/fiddler_client.egg-info}/PKG-INFO +2 -2
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler_client.egg-info/SOURCES.txt +3 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler_client.egg-info/requires.txt +1 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/setup.py +4 -1
- fiddler_client-3.4.0.dev1/fiddler/VERSION +0 -1
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/LICENSE.txt +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/MANIFEST.in +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/PUBLIC.md +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/README.md +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/configs.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/__init__.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/alert_rule.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/baseline.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/dataset.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/events.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/job.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/model.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/model_deployment.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/decorators.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/__init__.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/alert_record.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/base.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/baseline.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/custom_expression.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/dataset.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/events.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/file.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/job.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/model.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/model_artifact.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/model_deployment.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/organization.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/project.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/surrogate.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/user.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/webhook.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/libs/__init__.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/libs/json_encoder.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/libs/semver.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/packtools/__init__.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/packtools/gem.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/packtools/keras_ig_helpers.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/packtools/template_model.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/__init__.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/custom_expression.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/dataset.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/events.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/filter_query.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/job.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/model.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/model_deployment.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/model_task_params.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/organization.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/project.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/response.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/server_info.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/webhook.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/__init__.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/__init__.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_alert_record.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_baseline.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_custom_metric.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_dataset.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_events.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_files.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_generate_model.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_job.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_mixin.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_model_artifact.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_model_deployment.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_model_surrogate.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_project.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_segment.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/conftest.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/test_json_encoder.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/test_logger.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/test_utils.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/utils.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/__init__.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/helpers.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/model_generator.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/validations.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/version.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/version.py +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler_client.egg-info/dependency_links.txt +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler_client.egg-info/top_level.txt +0 -0
- {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fiddler-client
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5.0.dev1
|
|
4
4
|
Summary: Python client for Fiddler Platform
|
|
5
5
|
Home-page: https://fiddler.ai
|
|
6
6
|
Author: Fiddler Labs
|
|
@@ -14,7 +14,7 @@ Requires-Dist: pip>=21.0
|
|
|
14
14
|
Requires-Dist: requests<3
|
|
15
15
|
Requires-Dist: requests-toolbelt
|
|
16
16
|
Requires-Dist: pandas>=1.2.5
|
|
17
|
-
Requires-Dist: pydantic
|
|
17
|
+
Requires-Dist: pydantic>=1.10.17
|
|
18
18
|
Requires-Dist: deprecated==1.2.14
|
|
19
19
|
Requires-Dist: tqdm
|
|
20
20
|
Requires-Dist: simplejson>=3.17.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.5.0.dev1
|
|
@@ -18,7 +18,7 @@ from fiddler.constants.model import ( # noqa
|
|
|
18
18
|
ModelTask,
|
|
19
19
|
)
|
|
20
20
|
from fiddler.constants.model_deployment import ArtifactType, DeploymentType # noqa
|
|
21
|
-
from fiddler.constants.xai import ExplainMethod # noqa
|
|
21
|
+
from fiddler.constants.xai import DownloadFormat, ExplainMethod # noqa
|
|
22
22
|
from fiddler.entities.alert_record import AlertRecord # noqa
|
|
23
23
|
from fiddler.entities.alert_rule import AlertRule # noqa
|
|
24
24
|
from fiddler.entities.baseline import Baseline, BaselineCompact # noqa
|
|
@@ -89,6 +89,7 @@ __all__ = [
|
|
|
89
89
|
'CompareTo',
|
|
90
90
|
'DataType',
|
|
91
91
|
'DeploymentType',
|
|
92
|
+
'DownloadFormat',
|
|
92
93
|
'EnvType',
|
|
93
94
|
'ExplainMethod',
|
|
94
95
|
'JobStatus',
|
|
@@ -4,7 +4,11 @@ from functools import cached_property
|
|
|
4
4
|
from uuid import UUID
|
|
5
5
|
|
|
6
6
|
from fiddler.configs import DEFAULT_CONNECTION_TIMEOUT, MIN_SERVER_VERSION
|
|
7
|
-
from fiddler.constants.common import
|
|
7
|
+
from fiddler.constants.common import (
|
|
8
|
+
CLIENT_NAME,
|
|
9
|
+
FIDDLER_CLIENT_NAME_HEADER,
|
|
10
|
+
FIDDLER_CLIENT_VERSION_HEADER,
|
|
11
|
+
)
|
|
8
12
|
from fiddler.decorators import handle_api_error
|
|
9
13
|
from fiddler.exceptions import IncompatibleClient
|
|
10
14
|
from fiddler.libs.http_client import RequestClient
|
|
@@ -52,6 +56,7 @@ class Connection:
|
|
|
52
56
|
|
|
53
57
|
self.request_headers = {
|
|
54
58
|
'Authorization': f'Bearer {token}',
|
|
59
|
+
FIDDLER_CLIENT_NAME_HEADER: CLIENT_NAME,
|
|
55
60
|
FIDDLER_CLIENT_VERSION_HEADER: __version__,
|
|
56
61
|
}
|
|
57
62
|
|
|
@@ -6,6 +6,8 @@ TIMESTAMP_FORMAT = '%Y-%m-%d %H:%M:%S.%f'
|
|
|
6
6
|
# Headers
|
|
7
7
|
CONTENT_TYPE_HEADER_KEY = 'Content-Type'
|
|
8
8
|
JSON_CONTENT_TYPE = 'application/json'
|
|
9
|
+
|
|
10
|
+
FIDDLER_CLIENT_NAME_HEADER = 'X-Fiddler-Client-Name'
|
|
9
11
|
FIDDLER_CLIENT_VERSION_HEADER = 'X-Fiddler-Client-Version'
|
|
10
12
|
|
|
11
13
|
# Multi-part upload
|
|
@@ -9,3 +9,12 @@ class ExplainMethod(str, enum.Enum):
|
|
|
9
9
|
PERMUTE = 'PERMUTE'
|
|
10
10
|
ZERO_RESET = 'ZERO_RESET'
|
|
11
11
|
MEAN_RESET = 'MEAN_RESET'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@enum.unique
|
|
15
|
+
class DownloadFormat(str, enum.Enum):
|
|
16
|
+
PARQUET = 'PARQUET'
|
|
17
|
+
CSV = 'CSV'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
DEFAULT_DOWNLOAD_CHUNK_SIZE = 1000
|
|
@@ -5,7 +5,7 @@ from datetime import datetime
|
|
|
5
5
|
from typing import Any, Iterator
|
|
6
6
|
from uuid import UUID
|
|
7
7
|
|
|
8
|
-
from pydantic import ValidationError
|
|
8
|
+
from pydantic.v1 import ValidationError
|
|
9
9
|
|
|
10
10
|
from fiddler.constants.alert_rule import AlertCondition, BinSize, CompareTo, Priority
|
|
11
11
|
from fiddler.decorators import handle_api_error
|
|
@@ -286,7 +286,7 @@ class AlertRule(
|
|
|
286
286
|
pagerduty_services=pagerduty_services,
|
|
287
287
|
pagerduty_severity=pagerduty_severity,
|
|
288
288
|
webhooks=webhooks,
|
|
289
|
-
).dict()
|
|
289
|
+
).dict(exclude_none=True)
|
|
290
290
|
except ValidationError as e:
|
|
291
291
|
logger.exception('Invalid input: The format of input is not correct')
|
|
292
292
|
raise e
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
from collections import namedtuple
|
|
5
|
+
from datetime import datetime, timezone
|
|
5
6
|
from io import BytesIO
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from typing import Any, Callable
|
|
@@ -10,7 +11,11 @@ from uuid import UUID
|
|
|
10
11
|
import pandas as pd
|
|
11
12
|
|
|
12
13
|
from fiddler.constants.dataset import EnvType
|
|
13
|
-
from fiddler.constants.xai import
|
|
14
|
+
from fiddler.constants.xai import (
|
|
15
|
+
DEFAULT_DOWNLOAD_CHUNK_SIZE,
|
|
16
|
+
DownloadFormat,
|
|
17
|
+
ExplainMethod,
|
|
18
|
+
)
|
|
14
19
|
from fiddler.decorators import handle_api_error
|
|
15
20
|
from fiddler.entities.job import Job
|
|
16
21
|
from fiddler.schemas.job import JobCompactResp
|
|
@@ -20,6 +25,7 @@ from fiddler.schemas.xai import (
|
|
|
20
25
|
RowDataSource,
|
|
21
26
|
SqlSliceQueryDataSource,
|
|
22
27
|
)
|
|
28
|
+
from fiddler.utils.decorators import check_version
|
|
23
29
|
from fiddler.utils.helpers import try_series_retype
|
|
24
30
|
from fiddler.utils.logger import get_logger
|
|
25
31
|
|
|
@@ -134,6 +140,97 @@ class XaiMixin:
|
|
|
134
140
|
df[column_name] = try_series_retype(df[column_name], dtype)
|
|
135
141
|
return df
|
|
136
142
|
|
|
143
|
+
@handle_api_error
|
|
144
|
+
def download_data( # pylint: disable=too-many-arguments
|
|
145
|
+
self,
|
|
146
|
+
output_dir: Path | str,
|
|
147
|
+
env_type: EnvType,
|
|
148
|
+
env_id: UUID | None = None,
|
|
149
|
+
start_time: datetime | None = None,
|
|
150
|
+
end_time: datetime | None = None,
|
|
151
|
+
segment_id: UUID | None = None,
|
|
152
|
+
segment_definition: UUID | None = None,
|
|
153
|
+
max_rows: int | None = None,
|
|
154
|
+
columns: list[str] | None = None,
|
|
155
|
+
chunk_size: int | None = DEFAULT_DOWNLOAD_CHUNK_SIZE,
|
|
156
|
+
fetch_vectors: bool | None = None,
|
|
157
|
+
output_format: DownloadFormat = DownloadFormat.PARQUET,
|
|
158
|
+
) -> None:
|
|
159
|
+
"""
|
|
160
|
+
Download data with a slice data configuration to PARQUET or CSV file.
|
|
161
|
+
|
|
162
|
+
:param output_dir: Path to download the file
|
|
163
|
+
:param env_type: Type of environment to query (PRODUCTION or PRE_PRODUCTION)
|
|
164
|
+
:param env_id: If PRE_PRODUCTION env selected, provide the uuid of the dataset to query
|
|
165
|
+
:param start_time: Start time to retrieve data, only for PRODUCTION env. If not time zone is indicated, we will infer UTC time zone.
|
|
166
|
+
:param start_time: End time to retrieve data, only for PRODUCTION env. If not time zone is indicated, we will infer UTC time zone.
|
|
167
|
+
:param segment_id: Optional segment UUID to query data using a saved segment associated with the model
|
|
168
|
+
:param segment_definition: Optional segment FQL definition to query data using an applied segment. This segment will not be saved to the model.
|
|
169
|
+
:param columns: Allows caller to explicitly specify list of columns to retrieve. Default to None which fetch all columns from the model.
|
|
170
|
+
:param max_rows: Number of maximum rows to fetch
|
|
171
|
+
:param chunk_size: Number of rows per chunk to download data. Default to 1000. You can increase that number for faster download if you query less than 1000 columns and don't have vector columns.
|
|
172
|
+
:param fetch_vectors: Whether the vectors columns are fetched or not. Default to False.
|
|
173
|
+
:param output_format: Format indicating if the result should be a CSV file or a PARQUET file. Default to PARQUET file.
|
|
174
|
+
"""
|
|
175
|
+
self._check_id_attributes()
|
|
176
|
+
|
|
177
|
+
output_dir = Path(output_dir)
|
|
178
|
+
if not output_dir.exists():
|
|
179
|
+
os.makedirs(output_dir)
|
|
180
|
+
|
|
181
|
+
payload: dict[str, Any] = {
|
|
182
|
+
'model_id': self.id,
|
|
183
|
+
'env_type': env_type,
|
|
184
|
+
'csv': True if output_format == DownloadFormat.CSV else False,
|
|
185
|
+
'column_names': columns,
|
|
186
|
+
}
|
|
187
|
+
if env_id:
|
|
188
|
+
payload['env_id'] = env_id
|
|
189
|
+
if start_time or end_time:
|
|
190
|
+
payload['time_filter'] = {
|
|
191
|
+
'start_time': start_time.astimezone(timezone.utc).strftime(
|
|
192
|
+
'%Y-%m-%d %H:%M:%S'
|
|
193
|
+
)
|
|
194
|
+
if start_time
|
|
195
|
+
else None,
|
|
196
|
+
'end_time': end_time.astimezone(timezone.utc).strftime(
|
|
197
|
+
'%Y-%m-%d %H:%M:%S'
|
|
198
|
+
)
|
|
199
|
+
if end_time
|
|
200
|
+
else None,
|
|
201
|
+
'time_zone': 'UTC',
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if segment_id or segment_definition:
|
|
205
|
+
payload['segment'] = {'id': segment_id, 'definition': segment_definition}
|
|
206
|
+
|
|
207
|
+
if max_rows:
|
|
208
|
+
payload['num_samples'] = max_rows
|
|
209
|
+
|
|
210
|
+
if chunk_size:
|
|
211
|
+
payload['chunk_size'] = chunk_size
|
|
212
|
+
|
|
213
|
+
if fetch_vectors:
|
|
214
|
+
payload['fetch_vectors'] = fetch_vectors
|
|
215
|
+
|
|
216
|
+
file_path = os.path.join(
|
|
217
|
+
output_dir,
|
|
218
|
+
'output.csv' if output_format == DownloadFormat.CSV else 'output.parquet',
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
with self._client().post(
|
|
222
|
+
url='/v3/analytics/download-slice-data', data=payload
|
|
223
|
+
) as resp:
|
|
224
|
+
# Download file
|
|
225
|
+
with open(file_path, 'wb') as f:
|
|
226
|
+
for chunk in resp.iter_content(chunk_size=chunk_size):
|
|
227
|
+
if chunk:
|
|
228
|
+
f.write(chunk)
|
|
229
|
+
|
|
230
|
+
logger.info(
|
|
231
|
+
'Data succesfully downloaded',
|
|
232
|
+
)
|
|
233
|
+
|
|
137
234
|
@handle_api_error
|
|
138
235
|
def download_slice( # pylint: disable=too-many-arguments
|
|
139
236
|
self,
|
|
@@ -536,6 +633,7 @@ class XaiMixin:
|
|
|
536
633
|
'API response.'
|
|
537
634
|
)
|
|
538
635
|
|
|
636
|
+
@check_version(version_expr='>=24.11.1')
|
|
539
637
|
@handle_api_error
|
|
540
638
|
def upload_feature_impact(
|
|
541
639
|
self, feature_impact_map: dict, update: bool = False
|
|
@@ -34,8 +34,8 @@ class IncompatibleClient(BaseError):
|
|
|
34
34
|
# @TODO - Add link to compatibility matrix doc
|
|
35
35
|
)
|
|
36
36
|
|
|
37
|
-
def __init__(self, server_version: str) -> None:
|
|
38
|
-
self.message = self.message.format(
|
|
37
|
+
def __init__(self, server_version: str, message: str | None = None) -> None:
|
|
38
|
+
self.message = message or self.message.format(
|
|
39
39
|
client_version=__version__, server_version=server_version
|
|
40
40
|
)
|
|
41
41
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# type: ignore
|
|
2
|
+
# TODO: do type-checking soon: https://github.com/fiddler-anyprem/hadron/issues/25
|
|
3
|
+
|
|
4
|
+
# Note(JP): allow for type hints using strings (so that for example
|
|
5
|
+
# "PartnerAppAuthProvider" can be used as a type hint w/o having to import the
|
|
6
|
+
# class).
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
from collections import namedtuple
|
|
11
|
+
from typing import Optional
|
|
12
|
+
|
|
13
|
+
from fiddler.exceptions import BaseError
|
|
14
|
+
from fiddler.utils.logger import get_logger
|
|
15
|
+
|
|
16
|
+
logger = get_logger(__name__)
|
|
17
|
+
|
|
18
|
+
AwsSageMakerAuthConfig = namedtuple('AwsSageMakerAuthConfig', ['arn', 'url'])
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _read_env_for_aws_sagemaker_or_raise() -> Optional[AwsSageMakerAuthConfig]:
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
Raise `fiddler.exceptions.BaseError` when the environment appears to be
|
|
25
|
+
misconfigured.
|
|
26
|
+
"""
|
|
27
|
+
av = os.getenv("AWS_PARTNER_APP_AUTH")
|
|
28
|
+
|
|
29
|
+
if av is None:
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
if av.lower().strip() != "true":
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
# User has declared intent: activate SageMaker authentication. Require
|
|
36
|
+
# other environment variables to be set.
|
|
37
|
+
keys = ("AWS_PARTNER_APP_ARN", "AWS_PARTNER_APP_URL")
|
|
38
|
+
for k in keys:
|
|
39
|
+
errmsg = f"AWS_PARTNER_APP_AUTH is set to `{av}`, but {k} is not set"
|
|
40
|
+
if os.getenv(k) is None:
|
|
41
|
+
# Future: maybe have a ConfigError type?
|
|
42
|
+
raise BaseError(errmsg)
|
|
43
|
+
|
|
44
|
+
# Future: potentially do validation for got error messages, but be sure
|
|
45
|
+
# that the validation isn't getting in the way, _ever_.
|
|
46
|
+
|
|
47
|
+
# Remove leading and trailing whitespace: that's a safe operation, and
|
|
48
|
+
# always a user/config "error". That we can correct for.
|
|
49
|
+
arn = os.getenv("AWS_PARTNER_APP_ARN").strip() # type: ignore[union-attr]
|
|
50
|
+
url = os.getenv("AWS_PARTNER_APP_URL").strip() # type: ignore[union-attr]
|
|
51
|
+
return AwsSageMakerAuthConfig(arn, url)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _import_sm_sdk(c: AwsSageMakerAuthConfig): # -> "PartnerAppAuthProvider":
|
|
55
|
+
"""
|
|
56
|
+
Return `sagemaker.PartnerAppAuthProvider` instance or raise an exception.
|
|
57
|
+
"""
|
|
58
|
+
try:
|
|
59
|
+
from sagemaker import PartnerAppAuthProvider
|
|
60
|
+
except Exception as exc:
|
|
61
|
+
errmsg = (
|
|
62
|
+
f"The AWS_PARTNER_APP_* environment variables are set, but "
|
|
63
|
+
f"importing a dependency failed: {exc}"
|
|
64
|
+
)
|
|
65
|
+
raise BaseError(errmsg)
|
|
66
|
+
|
|
67
|
+
# Note(JP): can initialization of this auth provider object fail? Does it
|
|
68
|
+
# use Internet resources? Update 1: this call is expected to fail with e.g.
|
|
69
|
+
# `ValueError: Must specify a valid AWS_PARTNER_APP_ARN environment
|
|
70
|
+
# variable` when this env var is not set. Update 2: this does indeed deeper
|
|
71
|
+
# validation of the user-given config values. May throw for example
|
|
72
|
+
# "ValueError: Must specify a valid AWS_PARTNER_APP_ARN environment
|
|
73
|
+
# variable" when something non-ARN-looking has been provided. That is, we
|
|
74
|
+
# can (and should) skip validating these env var values and lave this job
|
|
75
|
+
# to the SM SDK.
|
|
76
|
+
p = PartnerAppAuthProvider()
|
|
77
|
+
logger.info("initialized AWS SageMaker authentication provider: %s", p)
|
|
78
|
+
return p
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def conditionally_init_aws_sm_auth(): # -> Optional["PartnerAppAuthProvider"]:
|
|
82
|
+
"""
|
|
83
|
+
Return `None` or `PartnerAppAuthProvider` instance.
|
|
84
|
+
|
|
85
|
+
Raise an exception upon configuration error or when dependencies are
|
|
86
|
+
missing.
|
|
87
|
+
"""
|
|
88
|
+
aws_sm_auth_cfg = _read_env_for_aws_sagemaker_or_raise()
|
|
89
|
+
|
|
90
|
+
logger.debug("auth config: %s", aws_sm_auth_cfg)
|
|
91
|
+
if aws_sm_auth_cfg is not None:
|
|
92
|
+
return _import_sm_sdk(aws_sm_auth_cfg)
|
|
93
|
+
|
|
94
|
+
# Just to make this expected case explicit.
|
|
95
|
+
return None
|
|
@@ -8,6 +8,7 @@ import requests
|
|
|
8
8
|
import simplejson
|
|
9
9
|
from requests.adapters import HTTPAdapter
|
|
10
10
|
|
|
11
|
+
import fiddler.libs.aws
|
|
11
12
|
from fiddler.constants.common import JSON_CONTENT_TYPE
|
|
12
13
|
from fiddler.exceptions import ( # pylint: disable=redefined-builtin
|
|
13
14
|
ConnError,
|
|
@@ -20,6 +21,15 @@ from fiddler.utils.logger import get_logger
|
|
|
20
21
|
logger = get_logger(__name__)
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
# Note(JP): this is doing conditional runtime modification for AWS Hadron /
|
|
25
|
+
# SageMaker, depending on
|
|
26
|
+
# - environment variables set by the user
|
|
27
|
+
# - importability of the AWS sagemaker Python SDK
|
|
28
|
+
# TODO: type annotation w/o having to import PartnerAppAuthProvider? This thing
|
|
29
|
+
# is either None or an instantiated auth provider.
|
|
30
|
+
_AWS_SM_AUTH_PROVIDER = fiddler.libs.aws.conditionally_init_aws_sm_auth() # type: ignore
|
|
31
|
+
|
|
32
|
+
|
|
23
33
|
class RequestClient:
|
|
24
34
|
def __init__(
|
|
25
35
|
self,
|
|
@@ -34,11 +44,23 @@ class RequestClient:
|
|
|
34
44
|
self.headers = headers
|
|
35
45
|
self.headers.update({'Content-Type': JSON_CONTENT_TYPE})
|
|
36
46
|
self.session = requests.Session()
|
|
47
|
+
|
|
48
|
+
# Note(JP): from the AWS SageMaker partner app guide.
|
|
49
|
+
if _AWS_SM_AUTH_PROVIDER is not None:
|
|
50
|
+
# Get callback class (`RequestsAuth` type`) from SM auth provider,
|
|
51
|
+
# and decorate the `requests` session object with that. This is
|
|
52
|
+
# enabling the magic of automatically mutating request headers.
|
|
53
|
+
# Among others, this injects the SigV4 header.
|
|
54
|
+
self.session.auth = _AWS_SM_AUTH_PROVIDER.get_auth()
|
|
55
|
+
|
|
37
56
|
self.session.verify = verify
|
|
38
57
|
adapter = HTTPAdapter(
|
|
39
58
|
pool_connections=25,
|
|
40
59
|
pool_maxsize=25,
|
|
41
60
|
)
|
|
61
|
+
|
|
62
|
+
# Does mounting the custom HTTP adapter revert the session.auth
|
|
63
|
+
# change from above?
|
|
42
64
|
self.session.mount(self.base_url, adapter)
|
|
43
65
|
|
|
44
66
|
def call(
|
|
@@ -159,9 +159,9 @@ class IGTextAttributionsTF2Keras:
|
|
|
159
159
|
att, word_tokens, tokenizer, embedding_name, feature_label
|
|
160
160
|
)
|
|
161
161
|
gem_container = gem.GEMContainer(contents=[gem_text])
|
|
162
|
-
explanations_by_output[
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
explanations_by_output[self.output_cols[output_field_index]] = (
|
|
163
|
+
gem_container.render()
|
|
164
|
+
)
|
|
165
165
|
|
|
166
166
|
return explanations_by_output
|
|
167
167
|
|
|
@@ -195,10 +195,12 @@ class IGTabularAttributions:
|
|
|
195
195
|
'Parameter attr_input_names_mapping cannot be empty when IG is enabled.'
|
|
196
196
|
)
|
|
197
197
|
for output_field_index, att in enumerate(attributions):
|
|
198
|
-
explanations_by_output[
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
explanations_by_output[self.output_cols[output_field_index]] = (
|
|
199
|
+
get_tabular_attributions_for_output(
|
|
200
|
+
self.input_df,
|
|
201
|
+
att,
|
|
202
|
+
attr_input_names_mapping=attr_input_names_mapping,
|
|
203
|
+
)
|
|
202
204
|
)
|
|
203
205
|
return explanations_by_output
|
|
204
206
|
|
|
@@ -386,7 +388,7 @@ def xgb_shap_transform_scale(
|
|
|
386
388
|
base_value = 1 / (1 + np.exp(-untransformed_base_value))
|
|
387
389
|
|
|
388
390
|
# Computing the original_explanation_distance to construct the distance_coefficient later on
|
|
389
|
-
original_explanation_distance = np.sum(shap_values)
|
|
391
|
+
original_explanation_distance = np.sum(shap_values) # type: ignore
|
|
390
392
|
|
|
391
393
|
# Computing the distance between the model_prediction and the transformed base_value
|
|
392
394
|
distance_to_explain = model_prediction - base_value
|
|
@@ -2,7 +2,7 @@ from datetime import datetime
|
|
|
2
2
|
from typing import List, Optional, Union
|
|
3
3
|
from uuid import UUID
|
|
4
4
|
|
|
5
|
-
from pydantic import Field
|
|
5
|
+
from pydantic.v1 import Field
|
|
6
6
|
|
|
7
7
|
from fiddler.constants.alert_rule import AlertCondition, BinSize, CompareTo, Priority
|
|
8
8
|
from fiddler.schemas.base import BaseModel
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Any, Dict, List, Optional, Type, TypeVar, Literal
|
|
2
2
|
|
|
3
|
-
from pydantic import BaseModel, validator
|
|
3
|
+
from pydantic.v1 import BaseModel, validator
|
|
4
4
|
|
|
5
5
|
from fiddler.configs import DEFAULT_NUM_CLUSTERS, DEFAULT_NUM_TAGS
|
|
6
6
|
from fiddler.constants.model import CustomFeatureType
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
from typing import List, Union
|
|
2
2
|
|
|
3
|
-
from pydantic import BaseModel, Field
|
|
3
|
+
from pydantic.v1 import BaseModel, Field
|
|
4
4
|
|
|
5
|
-
from fiddler.schemas.custom_features import
|
|
5
|
+
from fiddler.schemas.custom_features import (
|
|
6
|
+
Multivariate,
|
|
7
|
+
VectorFeature,
|
|
8
|
+
TextEmbedding,
|
|
9
|
+
ImageEmbedding,
|
|
10
|
+
Enrichment,
|
|
11
|
+
)
|
|
6
12
|
|
|
7
13
|
|
|
8
14
|
class ModelSpec(BaseModel):
|
|
@@ -26,7 +32,7 @@ class ModelSpec(BaseModel):
|
|
|
26
32
|
metadata: List[str] = Field(default_factory=list)
|
|
27
33
|
"""Metadata columns"""
|
|
28
34
|
|
|
29
|
-
custom_features: List[
|
|
30
|
-
|
|
31
|
-
)
|
|
35
|
+
custom_features: List[
|
|
36
|
+
Union[Multivariate, VectorFeature, TextEmbedding, ImageEmbedding, Enrichment]
|
|
37
|
+
] = Field(default_factory=list)
|
|
32
38
|
"""Custom feature definitions"""
|