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.
Files changed (119) hide show
  1. {fiddler_client-3.4.0.dev1/fiddler_client.egg-info → fiddler_client-3.5.0.dev1}/PKG-INFO +2 -2
  2. fiddler_client-3.5.0.dev1/fiddler/VERSION +1 -0
  3. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/__init__.py +2 -1
  4. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/connection.py +6 -1
  5. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/common.py +2 -0
  6. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/xai.py +9 -0
  7. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/alert_rule.py +2 -2
  8. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/xai.py +99 -1
  9. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/exceptions.py +2 -2
  10. fiddler_client-3.5.0.dev1/fiddler/libs/aws.py +95 -0
  11. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/libs/http_client.py +22 -0
  12. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/packtools/project_attributions_helpers.py +10 -8
  13. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/alert_record.py +1 -1
  14. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/alert_rule.py +1 -1
  15. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/base.py +2 -2
  16. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/baseline.py +1 -1
  17. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/custom_features.py +1 -1
  18. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/file.py +1 -1
  19. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/model_schema.py +1 -1
  20. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/model_spec.py +11 -5
  21. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/user.py +1 -1
  22. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/xai.py +1 -1
  23. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/xai_params.py +1 -1
  24. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_alert_rule.py +110 -10
  25. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_model.py +11 -5
  26. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_webhook.py +6 -6
  27. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_xai.py +30 -0
  28. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/constants.py +3 -1
  29. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/test_connection.py +11 -1
  30. fiddler_client-3.5.0.dev1/fiddler/tests/test_sagemaker_auth.py +75 -0
  31. fiddler_client-3.5.0.dev1/fiddler/utils/decorators.py +48 -0
  32. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/logger.py +7 -0
  33. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1/fiddler_client.egg-info}/PKG-INFO +2 -2
  34. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler_client.egg-info/SOURCES.txt +3 -0
  35. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler_client.egg-info/requires.txt +1 -1
  36. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/setup.py +4 -1
  37. fiddler_client-3.4.0.dev1/fiddler/VERSION +0 -1
  38. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/LICENSE.txt +0 -0
  39. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/MANIFEST.in +0 -0
  40. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/PUBLIC.md +0 -0
  41. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/README.md +0 -0
  42. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/configs.py +0 -0
  43. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/__init__.py +0 -0
  44. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/alert_rule.py +0 -0
  45. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/baseline.py +0 -0
  46. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/dataset.py +0 -0
  47. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/events.py +0 -0
  48. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/job.py +0 -0
  49. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/model.py +0 -0
  50. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/constants/model_deployment.py +0 -0
  51. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/decorators.py +0 -0
  52. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/__init__.py +0 -0
  53. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/alert_record.py +0 -0
  54. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/base.py +0 -0
  55. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/baseline.py +0 -0
  56. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/custom_expression.py +0 -0
  57. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/dataset.py +0 -0
  58. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/events.py +0 -0
  59. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/file.py +0 -0
  60. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/job.py +0 -0
  61. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/model.py +0 -0
  62. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/model_artifact.py +0 -0
  63. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/model_deployment.py +0 -0
  64. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/organization.py +0 -0
  65. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/project.py +0 -0
  66. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/surrogate.py +0 -0
  67. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/user.py +0 -0
  68. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/entities/webhook.py +0 -0
  69. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/libs/__init__.py +0 -0
  70. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/libs/json_encoder.py +0 -0
  71. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/libs/semver.py +0 -0
  72. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/packtools/__init__.py +0 -0
  73. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/packtools/gem.py +0 -0
  74. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/packtools/keras_ig_helpers.py +0 -0
  75. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/packtools/template_model.py +0 -0
  76. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/__init__.py +0 -0
  77. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/custom_expression.py +0 -0
  78. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/dataset.py +0 -0
  79. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/events.py +0 -0
  80. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/filter_query.py +0 -0
  81. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/job.py +0 -0
  82. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/model.py +0 -0
  83. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/model_deployment.py +0 -0
  84. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/model_task_params.py +0 -0
  85. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/organization.py +0 -0
  86. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/project.py +0 -0
  87. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/response.py +0 -0
  88. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/server_info.py +0 -0
  89. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/schemas/webhook.py +0 -0
  90. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/__init__.py +0 -0
  91. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/__init__.py +0 -0
  92. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_alert_record.py +0 -0
  93. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_baseline.py +0 -0
  94. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_custom_metric.py +0 -0
  95. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_dataset.py +0 -0
  96. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_events.py +0 -0
  97. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_files.py +0 -0
  98. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_generate_model.py +0 -0
  99. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_job.py +0 -0
  100. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_mixin.py +0 -0
  101. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_model_artifact.py +0 -0
  102. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_model_deployment.py +0 -0
  103. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_model_surrogate.py +0 -0
  104. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_project.py +0 -0
  105. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/apis/test_segment.py +0 -0
  106. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/conftest.py +0 -0
  107. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/test_json_encoder.py +0 -0
  108. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/test_logger.py +0 -0
  109. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/test_utils.py +0 -0
  110. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/tests/utils.py +0 -0
  111. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/__init__.py +0 -0
  112. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/helpers.py +0 -0
  113. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/model_generator.py +0 -0
  114. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/validations.py +0 -0
  115. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/utils/version.py +0 -0
  116. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler/version.py +0 -0
  117. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler_client.egg-info/dependency_links.txt +0 -0
  118. {fiddler_client-3.4.0.dev1 → fiddler_client-3.5.0.dev1}/fiddler_client.egg-info/top_level.txt +0 -0
  119. {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.4.0.dev1
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<2,>=1.10.15
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 CLIENT_NAME, FIDDLER_CLIENT_VERSION_HEADER
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 ExplainMethod
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
- self.output_cols[output_field_index]
164
- ] = gem_container.render()
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
- self.output_cols[output_field_index]
200
- ] = get_tabular_attributions_for_output(
201
- self.input_df, att, attr_input_names_mapping=attr_input_names_mapping
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 Optional
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.schemas.base import BaseModel
8
8
 
@@ -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,5 +1,5 @@
1
- from pydantic import BaseModel as _BaseModel
2
- from pydantic import Extra
1
+ from pydantic.v1 import BaseModel as _BaseModel
2
+ from pydantic.v1 import Extra
3
3
 
4
4
 
5
5
  class BaseModel(_BaseModel):
@@ -2,7 +2,7 @@ from datetime import datetime
2
2
  from typing import Optional
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.schemas.base import BaseModel
8
8
  from fiddler.schemas.dataset import DatasetCompactResp
@@ -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,7 +1,7 @@
1
1
  from datetime import datetime
2
2
  from uuid import UUID
3
3
 
4
- from pydantic import Field
4
+ from pydantic.v1 import Field
5
5
 
6
6
  from fiddler.schemas.base import BaseModel
7
7
  from fiddler.schemas.user import UserCompactResp
@@ -1,6 +1,6 @@
1
1
  from typing import List, Optional, Union
2
2
 
3
- from pydantic import BaseModel
3
+ from pydantic.v1 import BaseModel
4
4
 
5
5
  from fiddler.constants.model import DataType
6
6
 
@@ -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 Multivariate, VectorFeature, TextEmbedding, ImageEmbedding, Enrichment
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[Union[Multivariate, VectorFeature, TextEmbedding, ImageEmbedding, Enrichment]] = Field(
30
- default_factory=list
31
- )
35
+ custom_features: List[
36
+ Union[Multivariate, VectorFeature, TextEmbedding, ImageEmbedding, Enrichment]
37
+ ] = Field(default_factory=list)
32
38
  """Custom feature definitions"""
@@ -1,6 +1,6 @@
1
1
  from uuid import UUID
2
2
 
3
- from pydantic import BaseModel
3
+ from pydantic.v1 import BaseModel
4
4
 
5
5
 
6
6
  class UserCompactResp(BaseModel):
@@ -1,7 +1,7 @@
1
1
  from typing import Dict, Optional, Union
2
2
  from uuid import UUID
3
3
 
4
- from pydantic import Field
4
+ from pydantic.v1 import Field
5
5
 
6
6
  from fiddler.constants.dataset import EnvType
7
7
  from fiddler.schemas.base import BaseModel
@@ -1,6 +1,6 @@
1
1
  from typing import List, Optional
2
2
 
3
- from pydantic import BaseModel
3
+ from pydantic.v1 import BaseModel
4
4
 
5
5
 
6
6
  class XaiParams(BaseModel):