arize 8.0.0a22__py3-none-any.whl → 8.0.0a23__py3-none-any.whl

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 (166) hide show
  1. arize/__init__.py +17 -9
  2. arize/_exporter/client.py +55 -36
  3. arize/_exporter/parsers/tracing_data_parser.py +41 -30
  4. arize/_exporter/validation.py +3 -3
  5. arize/_flight/client.py +207 -76
  6. arize/_generated/api_client/__init__.py +30 -6
  7. arize/_generated/api_client/api/__init__.py +1 -0
  8. arize/_generated/api_client/api/datasets_api.py +864 -190
  9. arize/_generated/api_client/api/experiments_api.py +167 -131
  10. arize/_generated/api_client/api/projects_api.py +1197 -0
  11. arize/_generated/api_client/api_client.py +2 -2
  12. arize/_generated/api_client/configuration.py +42 -34
  13. arize/_generated/api_client/exceptions.py +2 -2
  14. arize/_generated/api_client/models/__init__.py +15 -4
  15. arize/_generated/api_client/models/dataset.py +10 -10
  16. arize/_generated/api_client/models/dataset_example.py +111 -0
  17. arize/_generated/api_client/models/dataset_example_update.py +100 -0
  18. arize/_generated/api_client/models/dataset_version.py +13 -13
  19. arize/_generated/api_client/models/datasets_create_request.py +16 -8
  20. arize/_generated/api_client/models/datasets_examples_insert_request.py +100 -0
  21. arize/_generated/api_client/models/datasets_examples_list200_response.py +106 -0
  22. arize/_generated/api_client/models/datasets_examples_update_request.py +102 -0
  23. arize/_generated/api_client/models/datasets_list200_response.py +10 -4
  24. arize/_generated/api_client/models/experiment.py +14 -16
  25. arize/_generated/api_client/models/experiment_run.py +108 -0
  26. arize/_generated/api_client/models/experiment_run_create.py +102 -0
  27. arize/_generated/api_client/models/experiments_create_request.py +16 -10
  28. arize/_generated/api_client/models/experiments_list200_response.py +10 -4
  29. arize/_generated/api_client/models/experiments_runs_list200_response.py +19 -5
  30. arize/_generated/api_client/models/{error.py → pagination_metadata.py} +13 -11
  31. arize/_generated/api_client/models/primitive_value.py +172 -0
  32. arize/_generated/api_client/models/problem.py +100 -0
  33. arize/_generated/api_client/models/project.py +99 -0
  34. arize/_generated/api_client/models/{datasets_list_examples200_response.py → projects_create_request.py} +13 -11
  35. arize/_generated/api_client/models/projects_list200_response.py +106 -0
  36. arize/_generated/api_client/rest.py +2 -2
  37. arize/_generated/api_client/test/test_dataset.py +4 -2
  38. arize/_generated/api_client/test/test_dataset_example.py +56 -0
  39. arize/_generated/api_client/test/test_dataset_example_update.py +52 -0
  40. arize/_generated/api_client/test/test_dataset_version.py +7 -2
  41. arize/_generated/api_client/test/test_datasets_api.py +27 -13
  42. arize/_generated/api_client/test/test_datasets_create_request.py +8 -4
  43. arize/_generated/api_client/test/{test_datasets_list_examples200_response.py → test_datasets_examples_insert_request.py} +19 -15
  44. arize/_generated/api_client/test/test_datasets_examples_list200_response.py +66 -0
  45. arize/_generated/api_client/test/test_datasets_examples_update_request.py +61 -0
  46. arize/_generated/api_client/test/test_datasets_list200_response.py +9 -3
  47. arize/_generated/api_client/test/test_experiment.py +2 -4
  48. arize/_generated/api_client/test/test_experiment_run.py +56 -0
  49. arize/_generated/api_client/test/test_experiment_run_create.py +54 -0
  50. arize/_generated/api_client/test/test_experiments_api.py +6 -6
  51. arize/_generated/api_client/test/test_experiments_create_request.py +9 -6
  52. arize/_generated/api_client/test/test_experiments_list200_response.py +9 -5
  53. arize/_generated/api_client/test/test_experiments_runs_list200_response.py +15 -5
  54. arize/_generated/api_client/test/test_pagination_metadata.py +53 -0
  55. arize/_generated/api_client/test/{test_error.py → test_primitive_value.py} +13 -14
  56. arize/_generated/api_client/test/test_problem.py +57 -0
  57. arize/_generated/api_client/test/test_project.py +58 -0
  58. arize/_generated/api_client/test/test_projects_api.py +59 -0
  59. arize/_generated/api_client/test/test_projects_create_request.py +54 -0
  60. arize/_generated/api_client/test/test_projects_list200_response.py +70 -0
  61. arize/_generated/api_client_README.md +43 -29
  62. arize/_generated/protocol/flight/flight_pb2.py +400 -0
  63. arize/_lazy.py +27 -19
  64. arize/client.py +268 -55
  65. arize/config.py +365 -116
  66. arize/constants/__init__.py +1 -0
  67. arize/constants/config.py +11 -4
  68. arize/constants/ml.py +6 -4
  69. arize/constants/openinference.py +2 -0
  70. arize/constants/pyarrow.py +2 -0
  71. arize/constants/spans.py +3 -1
  72. arize/datasets/__init__.py +1 -0
  73. arize/datasets/client.py +299 -84
  74. arize/datasets/errors.py +32 -2
  75. arize/datasets/validation.py +18 -8
  76. arize/embeddings/__init__.py +2 -0
  77. arize/embeddings/auto_generator.py +23 -19
  78. arize/embeddings/base_generators.py +89 -36
  79. arize/embeddings/constants.py +2 -0
  80. arize/embeddings/cv_generators.py +26 -4
  81. arize/embeddings/errors.py +27 -5
  82. arize/embeddings/nlp_generators.py +31 -12
  83. arize/embeddings/tabular_generators.py +32 -20
  84. arize/embeddings/usecases.py +12 -2
  85. arize/exceptions/__init__.py +1 -0
  86. arize/exceptions/auth.py +11 -1
  87. arize/exceptions/base.py +29 -4
  88. arize/exceptions/models.py +21 -2
  89. arize/exceptions/parameters.py +31 -0
  90. arize/exceptions/spaces.py +12 -1
  91. arize/exceptions/types.py +86 -7
  92. arize/exceptions/values.py +220 -20
  93. arize/experiments/__init__.py +1 -0
  94. arize/experiments/client.py +389 -285
  95. arize/experiments/evaluators/__init__.py +1 -0
  96. arize/experiments/evaluators/base.py +74 -41
  97. arize/experiments/evaluators/exceptions.py +6 -3
  98. arize/experiments/evaluators/executors.py +121 -73
  99. arize/experiments/evaluators/rate_limiters.py +106 -57
  100. arize/experiments/evaluators/types.py +34 -7
  101. arize/experiments/evaluators/utils.py +65 -27
  102. arize/experiments/functions.py +103 -101
  103. arize/experiments/tracing.py +52 -44
  104. arize/experiments/types.py +56 -31
  105. arize/logging.py +54 -22
  106. arize/models/__init__.py +1 -0
  107. arize/models/batch_validation/__init__.py +1 -0
  108. arize/models/batch_validation/errors.py +543 -65
  109. arize/models/batch_validation/validator.py +339 -300
  110. arize/models/bounded_executor.py +20 -7
  111. arize/models/casting.py +75 -29
  112. arize/models/client.py +326 -107
  113. arize/models/proto.py +95 -40
  114. arize/models/stream_validation.py +42 -14
  115. arize/models/surrogate_explainer/__init__.py +1 -0
  116. arize/models/surrogate_explainer/mimic.py +24 -13
  117. arize/pre_releases.py +43 -0
  118. arize/projects/__init__.py +1 -0
  119. arize/projects/client.py +129 -0
  120. arize/regions.py +40 -0
  121. arize/spans/__init__.py +1 -0
  122. arize/spans/client.py +130 -106
  123. arize/spans/columns.py +13 -0
  124. arize/spans/conversion.py +54 -38
  125. arize/spans/validation/__init__.py +1 -0
  126. arize/spans/validation/annotations/__init__.py +1 -0
  127. arize/spans/validation/annotations/annotations_validation.py +6 -4
  128. arize/spans/validation/annotations/dataframe_form_validation.py +13 -11
  129. arize/spans/validation/annotations/value_validation.py +35 -11
  130. arize/spans/validation/common/__init__.py +1 -0
  131. arize/spans/validation/common/argument_validation.py +33 -8
  132. arize/spans/validation/common/dataframe_form_validation.py +35 -9
  133. arize/spans/validation/common/errors.py +211 -11
  134. arize/spans/validation/common/value_validation.py +80 -13
  135. arize/spans/validation/evals/__init__.py +1 -0
  136. arize/spans/validation/evals/dataframe_form_validation.py +28 -8
  137. arize/spans/validation/evals/evals_validation.py +34 -4
  138. arize/spans/validation/evals/value_validation.py +26 -3
  139. arize/spans/validation/metadata/__init__.py +1 -1
  140. arize/spans/validation/metadata/argument_validation.py +14 -5
  141. arize/spans/validation/metadata/dataframe_form_validation.py +26 -10
  142. arize/spans/validation/metadata/value_validation.py +24 -10
  143. arize/spans/validation/spans/__init__.py +1 -0
  144. arize/spans/validation/spans/dataframe_form_validation.py +34 -13
  145. arize/spans/validation/spans/spans_validation.py +35 -4
  146. arize/spans/validation/spans/value_validation.py +76 -7
  147. arize/types.py +293 -157
  148. arize/utils/__init__.py +1 -0
  149. arize/utils/arrow.py +31 -15
  150. arize/utils/cache.py +34 -6
  151. arize/utils/dataframe.py +19 -2
  152. arize/utils/online_tasks/__init__.py +2 -0
  153. arize/utils/online_tasks/dataframe_preprocessor.py +53 -41
  154. arize/utils/openinference_conversion.py +44 -5
  155. arize/utils/proto.py +10 -0
  156. arize/utils/size.py +5 -3
  157. arize/version.py +3 -1
  158. {arize-8.0.0a22.dist-info → arize-8.0.0a23.dist-info}/METADATA +4 -3
  159. arize-8.0.0a23.dist-info/RECORD +174 -0
  160. {arize-8.0.0a22.dist-info → arize-8.0.0a23.dist-info}/WHEEL +1 -1
  161. arize-8.0.0a23.dist-info/licenses/LICENSE +176 -0
  162. arize-8.0.0a23.dist-info/licenses/NOTICE +13 -0
  163. arize/_generated/protocol/flight/export_pb2.py +0 -61
  164. arize/_generated/protocol/flight/ingest_pb2.py +0 -365
  165. arize-8.0.0a22.dist-info/RECORD +0 -146
  166. arize-8.0.0a22.dist-info/licenses/LICENSE.md +0 -12
@@ -1,5 +1,6 @@
1
+ """Value validation exception classes."""
2
+
1
3
  from collections.abc import Iterable
2
- from typing import Dict, List, Optional
3
4
 
4
5
  from arize.constants.ml import (
5
6
  MAX_FUTURE_YEARS_FROM_CURRENT_TIME,
@@ -13,13 +14,22 @@ from arize.logging import log_a_list
13
14
 
14
15
 
15
16
  class InvalidValueTimestamp(ValidationError):
17
+ """Raised when timestamp values are outside acceptable time range."""
18
+
16
19
  def __repr__(self) -> str:
20
+ """Return a string representation for debugging and logging."""
17
21
  return "Invalid_Timestamp_Value"
18
22
 
19
23
  def __init__(self, timestamp_col_name: str) -> None:
24
+ """Initialize the exception with timestamp validation context.
25
+
26
+ Args:
27
+ timestamp_col_name: Name of the column containing invalid timestamp values.
28
+ """
20
29
  self.timestamp_col_name = timestamp_col_name
21
30
 
22
31
  def error_message(self) -> str:
32
+ """Return the error message for this exception."""
23
33
  return (
24
34
  f"Prediction timestamp in {self.timestamp_col_name} is out of range. "
25
35
  f"Prediction timestamps must be within {MAX_FUTURE_YEARS_FROM_CURRENT_TIME} year "
@@ -30,32 +40,52 @@ class InvalidValueTimestamp(ValidationError):
30
40
 
31
41
 
32
42
  class InvalidValueMissingValue(ValidationError):
43
+ """Raised when required fields contain null or missing values."""
44
+
33
45
  def __repr__(self) -> str:
46
+ """Return a string representation for debugging and logging."""
34
47
  return "Invalid_Missing_Value"
35
48
 
36
49
  def __init__(
37
- self, name: str, wrong_values: str, column: Optional[str] = None
50
+ self, name: str, wrong_values: str, column: str | None = None
38
51
  ) -> None:
52
+ """Initialize the exception with missing value validation context.
53
+
54
+ Args:
55
+ name: Name of the field with missing values.
56
+ wrong_values: Description of the wrong values found (e.g., "null", "NaN").
57
+ column: Optional column name where missing values were found.
58
+ """
39
59
  self.name = name
40
60
  self.wrong_values = wrong_values
41
61
  self.column = column
42
62
 
43
63
  def error_message(self) -> str:
64
+ """Return the error message for this exception."""
44
65
  if self.name in ["Prediction ID", "Prediction Group ID", "Rank"]:
45
66
  return f"{self.name} column '{self.column}' must not contain {self.wrong_values} values."
46
- else:
47
- return f"{self.name} must not contain {self.wrong_values} values."
67
+ return f"{self.name} must not contain {self.wrong_values} values."
48
68
 
49
69
 
50
70
  class InvalidRankValue(ValidationError):
71
+ """Raised when ranking column values are outside acceptable range."""
72
+
51
73
  def __repr__(self) -> str:
74
+ """Return a string representation for debugging and logging."""
52
75
  return "Invalid_Rank_Value"
53
76
 
54
77
  def __init__(self, name: str, acceptable_range: str) -> None:
78
+ """Initialize the exception with rank validation context.
79
+
80
+ Args:
81
+ name: Name of the ranking column.
82
+ acceptable_range: Description of the acceptable value range.
83
+ """
55
84
  self.name = name
56
85
  self.acceptable_range = acceptable_range
57
86
 
58
87
  def error_message(self) -> str:
88
+ """Return the error message for this exception."""
59
89
  return (
60
90
  f"ranking column {self.name} is out of range. "
61
91
  f"Only values within {self.acceptable_range} are accepted. "
@@ -63,18 +93,30 @@ class InvalidRankValue(ValidationError):
63
93
 
64
94
 
65
95
  class InvalidStringLengthInColumn(ValidationError):
96
+ """Raised when string values in a column exceed length limits."""
97
+
66
98
  def __repr__(self) -> str:
99
+ """Return a string representation for debugging and logging."""
67
100
  return "Invalid_String_Length_In_Column"
68
101
 
69
102
  def __init__(
70
103
  self, schema_name: str, col_name: str, min_length: int, max_length: int
71
104
  ) -> None:
105
+ """Initialize the exception with string length validation context.
106
+
107
+ Args:
108
+ schema_name: Name of the schema field.
109
+ col_name: Name of the column with invalid string lengths.
110
+ min_length: Minimum acceptable string length.
111
+ max_length: Maximum acceptable string length.
112
+ """
72
113
  self.schema_name = schema_name
73
114
  self.col_name = col_name
74
115
  self.min_length = min_length
75
116
  self.max_length = max_length
76
117
 
77
118
  def error_message(self) -> str:
119
+ """Return the error message for this exception."""
78
120
  return (
79
121
  f"{self.schema_name} column '{self.col_name}' contains invalid values. "
80
122
  f"Only string values of length between {self.min_length} and {self.max_length} are accepted."
@@ -82,13 +124,22 @@ class InvalidStringLengthInColumn(ValidationError):
82
124
 
83
125
 
84
126
  class InvalidTagLength(ValidationError):
127
+ """Raised when tag values exceed maximum character length."""
128
+
85
129
  def __repr__(self) -> str:
130
+ """Return a string representation for debugging and logging."""
86
131
  return "Invalid_Tag_Length"
87
132
 
88
133
  def __init__(self, cols: Iterable) -> None:
134
+ """Initialize the exception with tag length validation context.
135
+
136
+ Args:
137
+ cols: Tag columns with values exceeding maximum character length.
138
+ """
89
139
  self.wrong_value_columns = cols
90
140
 
91
141
  def error_message(self) -> str:
142
+ """Return the error message for this exception."""
92
143
  return (
93
144
  f"Only tag values with less than or equal to {MAX_TAG_LENGTH} characters are supported. "
94
145
  f"The following tag columns have more than {MAX_TAG_LENGTH} characters: "
@@ -97,13 +148,22 @@ class InvalidTagLength(ValidationError):
97
148
 
98
149
 
99
150
  class InvalidRankingCategoryValue(ValidationError):
151
+ """Raised when ranking relevance labels contain invalid values."""
152
+
100
153
  def __repr__(self) -> str:
154
+ """Return a string representation for debugging and logging."""
101
155
  return "Invalid_Ranking_Relevance_Labels_Value"
102
156
 
103
157
  def __init__(self, name: str) -> None:
158
+ """Initialize the exception with ranking category validation context.
159
+
160
+ Args:
161
+ name: Name of the ranking relevance labels column.
162
+ """
104
163
  self.name = name
105
164
 
106
165
  def error_message(self) -> str:
166
+ """Return the error message for this exception."""
107
167
  return (
108
168
  f"ranking relevance labels '{self.name}' column contains invalid value"
109
169
  f"make sure empty string is not present"
@@ -111,15 +171,24 @@ class InvalidRankingCategoryValue(ValidationError):
111
171
 
112
172
 
113
173
  class InvalidBoundingBoxesCoordinates(ValidationError, Exception):
174
+ """Raised when bounding box coordinates are invalid or incorrectly formatted."""
175
+
114
176
  def __repr__(self) -> str:
177
+ """Return a string representation for debugging and logging."""
115
178
  return "Invalid_Bounding_Boxes_Coordinates"
116
179
 
117
- def __init__(self, reason) -> None:
180
+ def __init__(self, reason: str) -> None:
181
+ """Initialize the exception with bounding box coordinate validation context.
182
+
183
+ Args:
184
+ reason: Specific reason for invalid coordinates (e.g., "none_boxes",
185
+ "none_or_empty_box", "boxes_coordinates_wrong_format").
186
+ """
118
187
  self._check_valid_reason(reason)
119
188
  self.reason = reason
120
189
 
121
190
  @staticmethod
122
- def _check_valid_reason(reason):
191
+ def _check_valid_reason(reason: str) -> None:
123
192
  possible_reasons = (
124
193
  "none_boxes",
125
194
  "none_or_empty_box",
@@ -132,6 +201,7 @@ class InvalidBoundingBoxesCoordinates(ValidationError, Exception):
132
201
  )
133
202
 
134
203
  def error_message(self) -> str:
204
+ """Return the error message for this exception."""
135
205
  msg = "Invalid bounding boxes coordinates found. "
136
206
  if self.reason == "none_boxes":
137
207
  msg += (
@@ -154,15 +224,24 @@ class InvalidBoundingBoxesCoordinates(ValidationError, Exception):
154
224
 
155
225
 
156
226
  class InvalidBoundingBoxesCategories(ValidationError, Exception):
227
+ """Raised when bounding box categories are invalid or missing."""
228
+
157
229
  def __repr__(self) -> str:
230
+ """Return a string representation for debugging and logging."""
158
231
  return "Invalid_Bounding_Boxes_Categories"
159
232
 
160
- def __init__(self, reason) -> None:
233
+ def __init__(self, reason: str) -> None:
234
+ """Initialize the exception with bounding box category validation context.
235
+
236
+ Args:
237
+ reason: Specific reason for invalid categories (e.g., "none_category_list",
238
+ "none_category").
239
+ """
161
240
  self._check_valid_reason(reason)
162
241
  self.reason = reason
163
242
 
164
243
  @staticmethod
165
- def _check_valid_reason(reason):
244
+ def _check_valid_reason(reason: str) -> None:
166
245
  possible_reasons = (
167
246
  "none_category_list",
168
247
  "none_category",
@@ -174,6 +253,7 @@ class InvalidBoundingBoxesCategories(ValidationError, Exception):
174
253
  )
175
254
 
176
255
  def error_message(self) -> str:
256
+ """Return the error message for this exception."""
177
257
  msg = "Invalid bounding boxes categories found. "
178
258
  if self.reason == "none_category_list":
179
259
  msg += (
@@ -189,15 +269,24 @@ class InvalidBoundingBoxesCategories(ValidationError, Exception):
189
269
 
190
270
 
191
271
  class InvalidBoundingBoxesScores(ValidationError, Exception):
272
+ """Raised when bounding box confidence scores are invalid or out of bounds."""
273
+
192
274
  def __repr__(self) -> str:
275
+ """Return a string representation for debugging and logging."""
193
276
  return "Invalid_Bounding_Boxes_Scores"
194
277
 
195
- def __init__(self, reason) -> None:
278
+ def __init__(self, reason: str) -> None:
279
+ """Initialize the exception with bounding box score validation context.
280
+
281
+ Args:
282
+ reason: Specific reason for invalid scores (e.g., "none_score_list",
283
+ "scores_out_of_bounds").
284
+ """
196
285
  self._check_valid_reason(reason)
197
286
  self.reason = reason
198
287
 
199
288
  @staticmethod
200
- def _check_valid_reason(reason):
289
+ def _check_valid_reason(reason: str) -> None:
201
290
  possible_reasons = (
202
291
  "none_score_list",
203
292
  "scores_out_of_bounds",
@@ -209,6 +298,7 @@ class InvalidBoundingBoxesScores(ValidationError, Exception):
209
298
  )
210
299
 
211
300
  def error_message(self) -> str:
301
+ """Return the error message for this exception."""
212
302
  msg = "Invalid bounding boxes scores found. "
213
303
  if self.reason == "none_score_list":
214
304
  msg += (
@@ -224,18 +314,28 @@ class InvalidBoundingBoxesScores(ValidationError, Exception):
224
314
 
225
315
 
226
316
  class InvalidPolygonCoordinates(ValidationError, Exception):
317
+ """Raised when polygon coordinates are invalid or incorrectly formatted."""
318
+
227
319
  def __repr__(self) -> str:
320
+ """Return a string representation for debugging and logging."""
228
321
  return "Invalid_Polygon_Coordinates"
229
322
 
230
323
  def __init__(
231
- self, reason: str, coordinates: Optional[List[float]] = None
324
+ self, reason: str, coordinates: list[float] | None = None
232
325
  ) -> None:
326
+ """Initialize the exception with polygon coordinate validation context.
327
+
328
+ Args:
329
+ reason: Specific reason for invalid coordinates (e.g., "none_polygons",
330
+ "none_or_empty_polygon", "polygon_coordinates_wrong_format").
331
+ coordinates: Optional list of invalid coordinates for error reporting.
332
+ """
233
333
  self._check_valid_reason(reason)
234
334
  self.reason = reason
235
335
  self.coordinates = coordinates
236
336
 
237
337
  @staticmethod
238
- def _check_valid_reason(reason):
338
+ def _check_valid_reason(reason: str) -> None:
239
339
  possible_reasons = (
240
340
  "none_polygons",
241
341
  "none_or_empty_polygon",
@@ -250,6 +350,7 @@ class InvalidPolygonCoordinates(ValidationError, Exception):
250
350
  )
251
351
 
252
352
  def error_message(self) -> str:
353
+ """Return the error message for this exception."""
253
354
  msg = "Invalid polygon coordinates found. "
254
355
  if self.reason == "none_polygons":
255
356
  msg += (
@@ -285,15 +386,24 @@ class InvalidPolygonCoordinates(ValidationError, Exception):
285
386
 
286
387
 
287
388
  class InvalidPolygonCategories(ValidationError, Exception):
389
+ """Raised when polygon categories are invalid or missing."""
390
+
288
391
  def __repr__(self) -> str:
392
+ """Return a string representation for debugging and logging."""
289
393
  return "Invalid_Polygon_Categories"
290
394
 
291
- def __init__(self, reason) -> None:
395
+ def __init__(self, reason: str) -> None:
396
+ """Initialize the exception with polygon category validation context.
397
+
398
+ Args:
399
+ reason: Specific reason for invalid categories (e.g., "none_category_list",
400
+ "none_category").
401
+ """
292
402
  self._check_valid_reason(reason)
293
403
  self.reason = reason
294
404
 
295
405
  @staticmethod
296
- def _check_valid_reason(reason):
406
+ def _check_valid_reason(reason: str) -> None:
297
407
  possible_reasons = (
298
408
  "none_category_list",
299
409
  "none_category",
@@ -305,6 +415,7 @@ class InvalidPolygonCategories(ValidationError, Exception):
305
415
  )
306
416
 
307
417
  def error_message(self) -> str:
418
+ """Return the error message for this exception."""
308
419
  msg = "Invalid polygon categories found. "
309
420
  if self.reason == "none_category_list":
310
421
  msg += (
@@ -320,15 +431,24 @@ class InvalidPolygonCategories(ValidationError, Exception):
320
431
 
321
432
 
322
433
  class InvalidPolygonScores(ValidationError, Exception):
434
+ """Raised when polygon confidence scores are invalid or out of bounds."""
435
+
323
436
  def __repr__(self) -> str:
437
+ """Return a string representation for debugging and logging."""
324
438
  return "Invalid_Polygon_Scores"
325
439
 
326
- def __init__(self, reason) -> None:
440
+ def __init__(self, reason: str) -> None:
441
+ """Initialize the exception with polygon score validation context.
442
+
443
+ Args:
444
+ reason: Specific reason for invalid scores (e.g., "none_score_list",
445
+ "scores_out_of_bounds").
446
+ """
327
447
  self._check_valid_reason(reason)
328
448
  self.reason = reason
329
449
 
330
450
  @staticmethod
331
- def _check_valid_reason(reason):
451
+ def _check_valid_reason(reason: str) -> None:
332
452
  possible_reasons = (
333
453
  "none_score_list",
334
454
  "scores_out_of_bounds",
@@ -340,6 +460,7 @@ class InvalidPolygonScores(ValidationError, Exception):
340
460
  )
341
461
 
342
462
  def error_message(self) -> str:
463
+ """Return the error message for this exception."""
343
464
  msg = "Invalid polygon scores found. "
344
465
  if self.reason == "none_score_list":
345
466
  msg += (
@@ -355,15 +476,25 @@ class InvalidPolygonScores(ValidationError, Exception):
355
476
 
356
477
 
357
478
  class InvalidNumClassesMultiClassMap(ValidationError):
479
+ """Raised when multi-class dictionary contains invalid number of classes."""
480
+
358
481
  def __repr__(self) -> str:
482
+ """Return a string representation for debugging and logging."""
359
483
  return "Invalid_Num_classes_Multi_Class_Map"
360
484
 
361
485
  def __init__(
362
- self, dict_col_to_list_of_invalid_num_classes: Dict[str, List[str]]
486
+ self, dict_col_to_list_of_invalid_num_classes: dict[str, list[str]]
363
487
  ) -> None:
488
+ """Initialize the exception with multi-class number validation context.
489
+
490
+ Args:
491
+ dict_col_to_list_of_invalid_num_classes: Mapping of columns to lists of
492
+ invalid number of classes found.
493
+ """
364
494
  self.invalid_col_num_classes = dict_col_to_list_of_invalid_num_classes
365
495
 
366
496
  def error_message(self) -> str:
497
+ """Return the error message for this exception."""
367
498
  err_msg = ""
368
499
  for (
369
500
  col,
@@ -383,13 +514,22 @@ class InvalidNumClassesMultiClassMap(ValidationError):
383
514
 
384
515
 
385
516
  class InvalidMultiClassClassNameLength(ValidationError):
517
+ """Raised when multi-class class names exceed maximum length."""
518
+
386
519
  def __repr__(self) -> str:
520
+ """Return a string representation for debugging and logging."""
387
521
  return "Invalid_Multi_Class_Class_Name_Length"
388
522
 
389
- def __init__(self, invalid_col_class_name: Dict[str, set]) -> None:
523
+ def __init__(self, invalid_col_class_name: dict[str, set]) -> None:
524
+ """Initialize the exception with multi-class name length validation context.
525
+
526
+ Args:
527
+ invalid_col_class_name: Mapping of columns to sets of invalid class names.
528
+ """
390
529
  self.invalid_col_class_name = invalid_col_class_name
391
530
 
392
531
  def error_message(self) -> str:
532
+ """Return the error message for this exception."""
393
533
  err_msg = ""
394
534
  for col, class_names in self.invalid_col_class_name.items():
395
535
  # limit to 10
@@ -406,13 +546,22 @@ class InvalidMultiClassClassNameLength(ValidationError):
406
546
 
407
547
 
408
548
  class InvalidMultiClassPredScoreValue(ValidationError):
549
+ """Raised when multi-class prediction scores are outside valid range."""
550
+
409
551
  def __repr__(self) -> str:
552
+ """Return a string representation for debugging and logging."""
410
553
  return "Invalid_Multi_Class_Pred_Score_Value"
411
554
 
412
- def __init__(self, invalid_col_class_scores: Dict[str, set]) -> None:
555
+ def __init__(self, invalid_col_class_scores: dict[str, set]) -> None:
556
+ """Initialize the exception with multi-class prediction score validation context.
557
+
558
+ Args:
559
+ invalid_col_class_scores: Mapping of columns to sets of invalid scores.
560
+ """
413
561
  self.invalid_col_class_scores = invalid_col_class_scores
414
562
 
415
563
  def error_message(self) -> str:
564
+ """Return the error message for this exception."""
416
565
  err_msg = ""
417
566
  for col, scores in self.invalid_col_class_scores.items():
418
567
  # limit to 10
@@ -425,13 +574,22 @@ class InvalidMultiClassPredScoreValue(ValidationError):
425
574
 
426
575
 
427
576
  class InvalidMultiClassActScoreValue(ValidationError):
577
+ """Raised when multi-class actual scores are not 0 or 1."""
578
+
428
579
  def __repr__(self) -> str:
580
+ """Return a string representation for debugging and logging."""
429
581
  return "Invalid_Multi_Class_Act_Score_Value"
430
582
 
431
583
  def __init__(self, name: str) -> None:
584
+ """Initialize the exception with multi-class actual score validation context.
585
+
586
+ Args:
587
+ name: Name of the column with invalid actual scores.
588
+ """
432
589
  self.name = name
433
590
 
434
591
  def error_message(self) -> str:
592
+ """Return the error message for this exception."""
435
593
  return (
436
594
  f"Found at least one score in the '{self.name}' column that was invalid. "
437
595
  f"All scores (values) must be either 0 or 1."
@@ -439,17 +597,28 @@ class InvalidMultiClassActScoreValue(ValidationError):
439
597
 
440
598
 
441
599
  class InvalidMultiClassThresholdClasses(ValidationError):
600
+ """Raised when prediction and threshold score dictionaries have mismatched classes."""
601
+
442
602
  def __repr__(self) -> str:
603
+ """Return a string representation for debugging and logging."""
443
604
  return "Invalid_Multi_Class_Threshold_Classes"
444
605
 
445
606
  def __init__(
446
607
  self, name: str, prediction_class_set: set, threshold_class_set: set
447
608
  ) -> None:
609
+ """Initialize the exception with multi-class threshold validation context.
610
+
611
+ Args:
612
+ name: Name of the field being validated.
613
+ prediction_class_set: Set of classes in prediction scores dictionary.
614
+ threshold_class_set: Set of classes in threshold scores dictionary.
615
+ """
448
616
  self.name = name
449
617
  self.prediction_class_set = prediction_class_set
450
618
  self.threshold_class_set = threshold_class_set
451
619
 
452
620
  def error_message(self) -> str:
621
+ """Return the error message for this exception."""
453
622
  return (
454
623
  "Multi-Class Prediction Scores and Threshold Scores Dictionaries must contain the same "
455
624
  f"classes. The following classes of the Prediction Scores Dictionary are not in the Threshold "
@@ -460,13 +629,22 @@ class InvalidMultiClassThresholdClasses(ValidationError):
460
629
 
461
630
 
462
631
  class InvalidAdditionalHeaders(ValidationError):
632
+ """Raised when additional headers use reserved header names."""
633
+
463
634
  def __repr__(self) -> str:
635
+ """Return a string representation for debugging and logging."""
464
636
  return "Invalid_Additional_Headers"
465
637
 
466
638
  def __init__(self, invalid_headers: Iterable) -> None:
639
+ """Initialize the exception with invalid headers context.
640
+
641
+ Args:
642
+ invalid_headers: Headers that use reserved names.
643
+ """
467
644
  self.invalid_header_names = invalid_headers
468
645
 
469
646
  def error_message(self) -> str:
647
+ """Return the error message for this exception."""
470
648
  return (
471
649
  "Found invalid additional header, cannot use reserved headers named: "
472
650
  f"{', '.join(map(str, self.invalid_header_names))}."
@@ -474,14 +652,24 @@ class InvalidAdditionalHeaders(ValidationError):
474
652
 
475
653
 
476
654
  class InvalidRecord(ValidationError):
655
+ """Raised when records contain invalid or all-null column sets."""
656
+
477
657
  def __repr__(self) -> str:
658
+ """Return a string representation for debugging and logging."""
478
659
  return "Invalid_Record"
479
660
 
480
- def __init__(self, columns: List[str], indexes: List[int]) -> None:
661
+ def __init__(self, columns: list[str], indexes: list[int]) -> None:
662
+ """Initialize the exception with invalid record context.
663
+
664
+ Args:
665
+ columns: Columns that form an invalid all-null set.
666
+ indexes: Row indexes containing the invalid records.
667
+ """
481
668
  self.columns = columns
482
669
  self.indexes = indexes
483
670
 
484
671
  def error_message(self) -> str:
672
+ """Return the error message for this exception."""
485
673
  return (
486
674
  f"Invalid column set full of null values in one or more rows.\n"
487
675
  f"\nProblematic Column Set:\n{log_a_list(self.columns, 'and')}\n"
@@ -495,16 +683,28 @@ class InvalidRecord(ValidationError):
495
683
 
496
684
 
497
685
  class InvalidStringLength(Exception):
686
+ """Raised when a string value exceeds the allowed length."""
687
+
498
688
  def __init__(self, name: str, min_length: int, max_length: int) -> None:
689
+ """Initialize the exception with string length validation context.
690
+
691
+ Args:
692
+ name: Name of the field with invalid length.
693
+ min_length: Minimum acceptable string length.
694
+ max_length: Maximum acceptable string length.
695
+ """
499
696
  self.name = name
500
697
  self.min_length = min_length
501
698
  self.max_length = max_length
502
699
 
503
700
  def __repr__(self) -> str:
701
+ """Return a string representation for debugging and logging."""
504
702
  return "Invalid_String_Length"
505
703
 
506
704
  def __str__(self) -> str:
705
+ """Return a human-readable error message."""
507
706
  return self.error_message()
508
707
 
509
708
  def error_message(self) -> str:
709
+ """Return the error message for this exception."""
510
710
  return f"{self.name} must be of length between {self.min_length} and {self.max_length} characters."
@@ -0,0 +1 @@
1
+ """Experiment tracking and evaluation functionality for the Arize SDK."""