acryl-datahub-cloud 0.3.12rc3__py3-none-any.whl → 0.3.12rc4__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.

Potentially problematic release.


This version of acryl-datahub-cloud might be problematic. Click here for more details.

@@ -14,7 +14,7 @@ from typing import Optional, Union
14
14
 
15
15
  from typing_extensions import Self
16
16
 
17
- from acryl_datahub_cloud.sdk.assertion_input import (
17
+ from acryl_datahub_cloud.sdk.assertion_input.assertion_input import (
18
18
  ASSERTION_MONITOR_DEFAULT_TRAINING_LOOKBACK_WINDOW_DAYS,
19
19
  DEFAULT_DETECTION_MECHANISM,
20
20
  DEFAULT_SCHEDULE,
@@ -24,6 +24,7 @@ from acryl_datahub_cloud.sdk.assertion_input import (
24
24
  ExclusionWindowTypes,
25
25
  FixedRangeExclusionWindow,
26
26
  InferenceSensitivity,
27
+ TimeWindowSizeInputTypes,
27
28
  _DetectionMechanismTypes,
28
29
  )
29
30
  from acryl_datahub_cloud.sdk.entities.assertion import Assertion
@@ -85,21 +86,12 @@ class _HasSmartFunctionality:
85
86
  Mixin class that provides smart functionality for assertions.
86
87
  """
87
88
 
88
- _SUPPORTED_WITH_FILTER_ASSERTION_TYPES = (
89
- models.FreshnessAssertionInfoClass,
90
- models.VolumeAssertionInfoClass,
91
- )
92
-
93
89
  def __init__(
94
90
  self,
95
91
  *,
96
92
  sensitivity: InferenceSensitivity = DEFAULT_SENSITIVITY,
97
93
  exclusion_windows: list[ExclusionWindowTypes],
98
94
  training_data_lookback_days: int = ASSERTION_MONITOR_DEFAULT_TRAINING_LOOKBACK_WINDOW_DAYS,
99
- incident_behavior: list[AssertionIncidentBehavior],
100
- detection_mechanism: Optional[
101
- _DetectionMechanismTypes
102
- ] = DEFAULT_DETECTION_MECHANISM,
103
95
  ) -> None:
104
96
  """
105
97
  Initialize the smart functionality mixin.
@@ -115,8 +107,6 @@ class _HasSmartFunctionality:
115
107
  self._sensitivity = sensitivity
116
108
  self._exclusion_windows = exclusion_windows
117
109
  self._training_data_lookback_days = training_data_lookback_days
118
- self._incident_behavior = incident_behavior
119
- self._detection_mechanism = detection_mechanism
120
110
 
121
111
  @property
122
112
  def sensitivity(self) -> InferenceSensitivity:
@@ -130,14 +120,6 @@ class _HasSmartFunctionality:
130
120
  def training_data_lookback_days(self) -> int:
131
121
  return self._training_data_lookback_days
132
122
 
133
- @property
134
- def incident_behavior(self) -> list[AssertionIncidentBehavior]:
135
- return self._incident_behavior
136
-
137
- @property
138
- def detection_mechanism(self) -> Optional[_DetectionMechanismTypes]:
139
- return self._detection_mechanism
140
-
141
123
  @staticmethod
142
124
  def _get_sensitivity(monitor: Monitor) -> InferenceSensitivity:
143
125
  # 1. Check if the monitor has a sensitivity field
@@ -186,6 +168,115 @@ class _HasSmartFunctionality:
186
168
  assert isinstance(retrieved, int)
187
169
  return retrieved
188
170
 
171
+
172
+ class _AssertionPublic(ABC):
173
+ """
174
+ Abstract base class that represents a public facing assertion and contains the common properties of all assertions.
175
+ """
176
+
177
+ _SUPPORTED_WITH_FILTER_ASSERTION_TYPES = (
178
+ models.FreshnessAssertionInfoClass,
179
+ models.VolumeAssertionInfoClass,
180
+ )
181
+
182
+ def __init__(
183
+ self,
184
+ *,
185
+ urn: AssertionUrn,
186
+ dataset_urn: DatasetUrn,
187
+ display_name: str,
188
+ mode: AssertionMode,
189
+ tags: list[TagUrn],
190
+ incident_behavior: list[AssertionIncidentBehavior],
191
+ detection_mechanism: Optional[
192
+ _DetectionMechanismTypes
193
+ ] = DEFAULT_DETECTION_MECHANISM,
194
+ created_by: Optional[CorpUserUrn] = None,
195
+ created_at: Union[datetime, None] = None,
196
+ updated_by: Optional[CorpUserUrn] = None,
197
+ updated_at: Optional[datetime] = None,
198
+ ):
199
+ """
200
+ Initialize the public facing assertion class.
201
+
202
+ Args:
203
+ urn: The urn of the assertion.
204
+ dataset_urn: The urn of the dataset that the assertion is for.
205
+ display_name: The display name of the assertion.
206
+ mode: The mode of the assertion (active, inactive).
207
+ tags: The tags of the assertion.
208
+ created_by: The urn of the user that created the assertion.
209
+ created_at: The timestamp of when the assertion was created.
210
+ updated_by: The urn of the user that updated the assertion.
211
+ updated_at: The timestamp of when the assertion was updated.
212
+ """
213
+ self._urn = urn
214
+ self._dataset_urn = dataset_urn
215
+ self._display_name = display_name
216
+ self._mode = mode
217
+ self._incident_behavior = incident_behavior
218
+ self._detection_mechanism = detection_mechanism
219
+ self._created_by = created_by
220
+ self._created_at = created_at
221
+ self._updated_by = updated_by
222
+ self._updated_at = updated_at
223
+ self._tags = tags
224
+
225
+ @property
226
+ def urn(self) -> AssertionUrn:
227
+ return self._urn
228
+
229
+ @property
230
+ def dataset_urn(self) -> DatasetUrn:
231
+ return self._dataset_urn
232
+
233
+ @property
234
+ def display_name(self) -> str:
235
+ return self._display_name
236
+
237
+ @property
238
+ def mode(self) -> AssertionMode:
239
+ return self._mode
240
+
241
+ @property
242
+ def incident_behavior(self) -> list[AssertionIncidentBehavior]:
243
+ return self._incident_behavior
244
+
245
+ @property
246
+ def detection_mechanism(self) -> Optional[_DetectionMechanismTypes]:
247
+ return self._detection_mechanism
248
+
249
+ @property
250
+ def created_by(self) -> Optional[CorpUserUrn]:
251
+ return self._created_by
252
+
253
+ @property
254
+ def created_at(self) -> Union[datetime, None]:
255
+ return self._created_at
256
+
257
+ @property
258
+ def updated_by(self) -> Optional[CorpUserUrn]:
259
+ return self._updated_by
260
+
261
+ @property
262
+ def updated_at(self) -> Union[datetime, None]:
263
+ return self._updated_at
264
+
265
+ @property
266
+ def tags(self) -> list[TagUrn]:
267
+ return self._tags
268
+
269
+ @staticmethod
270
+ def _get_incident_behavior(assertion: Assertion) -> list[AssertionIncidentBehavior]:
271
+ incident_behaviors = []
272
+ for action in assertion.on_failure + assertion.on_success:
273
+ if action.type == models.AssertionActionTypeClass.RAISE_INCIDENT:
274
+ incident_behaviors.append(AssertionIncidentBehavior.RAISE_ON_FAIL)
275
+ elif action.type == models.AssertionActionTypeClass.RESOLVE_INCIDENT:
276
+ incident_behaviors.append(AssertionIncidentBehavior.RESOLVE_ON_PASS)
277
+
278
+ return incident_behaviors
279
+
189
280
  @staticmethod
190
281
  def _get_detection_mechanism(
191
282
  assertion: Assertion,
@@ -193,7 +284,7 @@ class _HasSmartFunctionality:
193
284
  default: Optional[_DetectionMechanismTypes] = DEFAULT_DETECTION_MECHANISM,
194
285
  ) -> Optional[_DetectionMechanismTypes]:
195
286
  """Get the detection mechanism from the monitor and assertion."""
196
- if not _HasSmartFunctionality._has_valid_monitor_info(monitor):
287
+ if not _AssertionPublic._has_valid_monitor_info(monitor):
197
288
  return default
198
289
 
199
290
  # 1. Check if the assertion has a parameters field
@@ -206,7 +297,7 @@ class _HasSmartFunctionality:
206
297
  )
207
298
  return default
208
299
 
209
- parameters = _HasSmartFunctionality._get_assertion_parameters(monitor, default)
300
+ parameters = _AssertionPublic._get_assertion_parameters(monitor, default)
210
301
  if parameters is None:
211
302
  return _warn_and_return_default_detection_mechanism("parameters", default)
212
303
 
@@ -218,11 +309,11 @@ class _HasSmartFunctionality:
218
309
  if assertion.info is None:
219
310
  return _warn_and_return_default_detection_mechanism("info", default)
220
311
  if isinstance(assertion.info, models.VolumeAssertionInfoClass):
221
- return _HasSmartFunctionality._get_volume_detection_mechanism(
312
+ return _AssertionPublic._get_volume_detection_mechanism(
222
313
  assertion, parameters, default
223
314
  )
224
315
  elif isinstance(assertion.info, models.FreshnessAssertionInfoClass):
225
- return _HasSmartFunctionality._get_freshness_detection_mechanism(
316
+ return _AssertionPublic._get_freshness_detection_mechanism(
226
317
  assertion, parameters, default
227
318
  )
228
319
  # TODO: Consider moving the detection mechanism logic to the assertion classes themselves e.g. _get_assertion_specific_detection_mechanism as an abstract method
@@ -236,53 +327,6 @@ class _HasSmartFunctionality:
236
327
  f"AssertionEvaluationParametersType {parameters.type} not supported"
237
328
  )
238
329
 
239
- @staticmethod
240
- def _has_valid_monitor_info(monitor: Monitor) -> bool:
241
- """Check if monitor has valid info and assertion monitor."""
242
-
243
- def _warn_and_return_false(field_name: str) -> bool:
244
- logger.warning(
245
- f"Monitor {monitor.urn} does not have an `{field_name}` field, defaulting detection mechanism to {DEFAULT_DETECTION_MECHANISM}"
246
- )
247
- return False
248
-
249
- if monitor.info is None:
250
- return _warn_and_return_false("info")
251
- if monitor.info.assertionMonitor is None:
252
- return _warn_and_return_false("assertionMonitor")
253
- if (
254
- monitor.info.assertionMonitor.assertions is None
255
- or len(monitor.info.assertionMonitor.assertions) == 0
256
- ):
257
- return _warn_and_return_false("assertionMonitor.assertions")
258
-
259
- return True
260
-
261
- @staticmethod
262
- def _get_assertion_parameters(
263
- monitor: Monitor,
264
- default: Optional[_DetectionMechanismTypes] = DEFAULT_DETECTION_MECHANISM,
265
- ) -> Optional[models.AssertionEvaluationParametersClass]:
266
- """Get the assertion parameters from the monitor."""
267
- # We know these are not None from _has_valid_monitor_info check
268
- assert (
269
- monitor is not None
270
- and monitor.info is not None
271
- and monitor.info.assertionMonitor is not None
272
- )
273
- assertion_monitor = monitor.info.assertionMonitor
274
- assert (
275
- assertion_monitor is not None and assertion_monitor.assertions is not None
276
- )
277
- assertions = assertion_monitor.assertions
278
-
279
- if assertions[0].parameters is None:
280
- logger.warning(
281
- f"Monitor {monitor.urn} does not have a assertionMonitor.assertions[0].parameters, defaulting detection mechanism to {default}"
282
- )
283
- return None
284
- return assertions[0].parameters
285
-
286
330
  @staticmethod
287
331
  def _get_freshness_detection_mechanism(
288
332
  assertion: Assertion,
@@ -302,7 +346,7 @@ class _HasSmartFunctionality:
302
346
  elif source_type == models.DatasetFreshnessSourceTypeClass.AUDIT_LOG:
303
347
  return DetectionMechanism.AUDIT_LOG
304
348
  elif source_type == models.DatasetFreshnessSourceTypeClass.FIELD_VALUE:
305
- return _HasSmartFunctionality._get_field_value_detection_mechanism(
349
+ return _AssertionPublic._get_field_value_detection_mechanism(
306
350
  assertion, parameters
307
351
  )
308
352
  elif source_type == models.DatasetFreshnessSourceTypeClass.DATAHUB_OPERATION:
@@ -332,7 +376,7 @@ class _HasSmartFunctionality:
332
376
  if source_type == models.DatasetVolumeSourceTypeClass.INFORMATION_SCHEMA:
333
377
  return DetectionMechanism.INFORMATION_SCHEMA
334
378
  elif source_type == models.DatasetVolumeSourceTypeClass.QUERY:
335
- additional_filter = _HasSmartFunctionality._get_additional_filter(assertion)
379
+ additional_filter = _AssertionPublic._get_additional_filter(assertion)
336
380
  return DetectionMechanism.QUERY(additional_filter=additional_filter)
337
381
  elif source_type == models.DatasetVolumeSourceTypeClass.DATAHUB_DATASET_PROFILE:
338
382
  return DetectionMechanism.DATASET_PROFILE
@@ -356,7 +400,7 @@ class _HasSmartFunctionality:
356
400
  return DEFAULT_DETECTION_MECHANISM
357
401
 
358
402
  column_name = field.path
359
- additional_filter = _HasSmartFunctionality._get_additional_filter(assertion)
403
+ additional_filter = _AssertionPublic._get_additional_filter(assertion)
360
404
 
361
405
  if field.kind == models.FreshnessFieldKindClass.LAST_MODIFIED:
362
406
  return DetectionMechanism.LAST_MODIFIED_COLUMN(
@@ -380,7 +424,7 @@ class _HasSmartFunctionality:
380
424
  if (
381
425
  not isinstance(
382
426
  assertion.info,
383
- _HasSmartFunctionality._SUPPORTED_WITH_FILTER_ASSERTION_TYPES,
427
+ _AssertionPublic._SUPPORTED_WITH_FILTER_ASSERTION_TYPES,
384
428
  )
385
429
  or assertion.info.filter is None
386
430
  ):
@@ -394,95 +438,52 @@ class _HasSmartFunctionality:
394
438
  )
395
439
  return assertion.info.filter.sql
396
440
 
441
+ @staticmethod
442
+ def _has_valid_monitor_info(monitor: Monitor) -> bool:
443
+ """Check if monitor has valid info and assertion monitor."""
397
444
 
398
- class _AssertionPublic(ABC):
399
- """
400
- Abstract base class that represents a public facing assertion and contains the common properties of all assertions.
401
- """
402
-
403
- def __init__(
404
- self,
405
- *,
406
- urn: AssertionUrn,
407
- dataset_urn: DatasetUrn,
408
- display_name: str,
409
- mode: AssertionMode,
410
- tags: list[TagUrn],
411
- created_by: Optional[CorpUserUrn] = None,
412
- created_at: Union[datetime, None] = None,
413
- updated_by: Optional[CorpUserUrn] = None,
414
- updated_at: Optional[datetime] = None,
415
- ):
416
- """
417
- Initialize the public facing assertion class.
418
-
419
- Args:
420
- urn: The urn of the assertion.
421
- dataset_urn: The urn of the dataset that the assertion is for.
422
- display_name: The display name of the assertion.
423
- mode: The mode of the assertion (active, inactive).
424
- tags: The tags of the assertion.
425
- created_by: The urn of the user that created the assertion.
426
- created_at: The timestamp of when the assertion was created.
427
- updated_by: The urn of the user that updated the assertion.
428
- updated_at: The timestamp of when the assertion was updated.
429
- """
430
- self._urn = urn
431
- self._dataset_urn = dataset_urn
432
- self._display_name = display_name
433
- self._mode = mode
434
- self._created_by = created_by
435
- self._created_at = created_at
436
- self._updated_by = updated_by
437
- self._updated_at = updated_at
438
- self._tags = tags
439
-
440
- @property
441
- def urn(self) -> AssertionUrn:
442
- return self._urn
443
-
444
- @property
445
- def dataset_urn(self) -> DatasetUrn:
446
- return self._dataset_urn
447
-
448
- @property
449
- def display_name(self) -> str:
450
- return self._display_name
451
-
452
- @property
453
- def mode(self) -> AssertionMode:
454
- return self._mode
455
-
456
- @property
457
- def created_by(self) -> Optional[CorpUserUrn]:
458
- return self._created_by
459
-
460
- @property
461
- def created_at(self) -> Union[datetime, None]:
462
- return self._created_at
463
-
464
- @property
465
- def updated_by(self) -> Optional[CorpUserUrn]:
466
- return self._updated_by
445
+ def _warn_and_return_false(field_name: str) -> bool:
446
+ logger.warning(
447
+ f"Monitor {monitor.urn} does not have an `{field_name}` field, defaulting detection mechanism to {DEFAULT_DETECTION_MECHANISM}"
448
+ )
449
+ return False
467
450
 
468
- @property
469
- def updated_at(self) -> Union[datetime, None]:
470
- return self._updated_at
451
+ if monitor.info is None:
452
+ return _warn_and_return_false("info")
453
+ if monitor.info.assertionMonitor is None:
454
+ return _warn_and_return_false("assertionMonitor")
455
+ if (
456
+ monitor.info.assertionMonitor.assertions is None
457
+ or len(monitor.info.assertionMonitor.assertions) == 0
458
+ ):
459
+ return _warn_and_return_false("assertionMonitor.assertions")
471
460
 
472
- @property
473
- def tags(self) -> list[TagUrn]:
474
- return self._tags
461
+ return True
475
462
 
476
463
  @staticmethod
477
- def _get_incident_behavior(assertion: Assertion) -> list[AssertionIncidentBehavior]:
478
- incident_behaviors = []
479
- for action in assertion.on_failure + assertion.on_success:
480
- if action.type == models.AssertionActionTypeClass.RAISE_INCIDENT:
481
- incident_behaviors.append(AssertionIncidentBehavior.RAISE_ON_FAIL)
482
- elif action.type == models.AssertionActionTypeClass.RESOLVE_INCIDENT:
483
- incident_behaviors.append(AssertionIncidentBehavior.RESOLVE_ON_PASS)
464
+ def _get_assertion_parameters(
465
+ monitor: Monitor,
466
+ default: Optional[_DetectionMechanismTypes] = DEFAULT_DETECTION_MECHANISM,
467
+ ) -> Optional[models.AssertionEvaluationParametersClass]:
468
+ """Get the assertion parameters from the monitor."""
469
+ # We know these are not None from _has_valid_monitor_info check
470
+ assert (
471
+ monitor is not None
472
+ and monitor.info is not None
473
+ and monitor.info.assertionMonitor is not None
474
+ )
475
+ assertion_monitor = monitor.info.assertionMonitor
476
+ assert (
477
+ assertion_monitor is not None and assertion_monitor.assertions is not None
478
+ )
479
+ assertions = assertion_monitor.assertions
484
480
 
485
- return incident_behaviors
481
+ if assertions[0].parameters is None:
482
+ logger.warning(
483
+ f"Monitor {monitor.urn} does not have a assertionMonitor.assertions[0].parameters, defaulting detection mechanism to {default}"
484
+ )
485
+ return None
486
+ return assertions[0].parameters
486
487
 
487
488
  @staticmethod
488
489
  def _get_created_by(assertion: Assertion) -> Optional[CorpUserUrn]:
@@ -619,8 +620,6 @@ class SmartFreshnessAssertion(_HasSchedule, _HasSmartFunctionality, _AssertionPu
619
620
  sensitivity=sensitivity,
620
621
  exclusion_windows=exclusion_windows,
621
622
  training_data_lookback_days=training_data_lookback_days,
622
- incident_behavior=incident_behavior,
623
- detection_mechanism=detection_mechanism,
624
623
  )
625
624
  # Then initialize the parent class
626
625
  _AssertionPublic.__init__(
@@ -629,6 +628,8 @@ class SmartFreshnessAssertion(_HasSchedule, _HasSmartFunctionality, _AssertionPu
629
628
  dataset_urn=dataset_urn,
630
629
  display_name=display_name,
631
630
  mode=mode,
631
+ incident_behavior=incident_behavior,
632
+ detection_mechanism=detection_mechanism,
632
633
  created_by=created_by,
633
634
  created_at=created_at,
634
635
  updated_by=updated_by,
@@ -717,8 +718,6 @@ class SmartVolumeAssertion(_HasSchedule, _HasSmartFunctionality, _AssertionPubli
717
718
  sensitivity=sensitivity,
718
719
  exclusion_windows=exclusion_windows,
719
720
  training_data_lookback_days=training_data_lookback_days,
720
- incident_behavior=incident_behavior,
721
- detection_mechanism=detection_mechanism,
722
721
  )
723
722
  # Then initialize the parent class
724
723
  _AssertionPublic.__init__(
@@ -727,6 +726,8 @@ class SmartVolumeAssertion(_HasSchedule, _HasSmartFunctionality, _AssertionPubli
727
726
  dataset_urn=dataset_urn,
728
727
  display_name=display_name,
729
728
  mode=mode,
729
+ incident_behavior=incident_behavior,
730
+ detection_mechanism=detection_mechanism,
730
731
  created_by=created_by,
731
732
  created_at=created_at,
732
733
  updated_by=updated_by,
@@ -760,8 +761,158 @@ class SmartVolumeAssertion(_HasSchedule, _HasSmartFunctionality, _AssertionPubli
760
761
  )
761
762
 
762
763
 
764
+ class FreshnessAssertion(_HasSchedule, _AssertionPublic):
765
+ """
766
+ A class that represents a freshness assertion.
767
+ """
768
+
769
+ def __init__(
770
+ self,
771
+ *,
772
+ urn: AssertionUrn,
773
+ dataset_urn: DatasetUrn,
774
+ display_name: str,
775
+ mode: AssertionMode,
776
+ schedule: models.CronScheduleClass,
777
+ freshness_schedule_check_type: Union[
778
+ str, models.FreshnessAssertionScheduleTypeClass
779
+ ],
780
+ lookback_window: Optional[TimeWindowSizeInputTypes],
781
+ tags: list[TagUrn],
782
+ incident_behavior: list[AssertionIncidentBehavior],
783
+ detection_mechanism: Optional[
784
+ _DetectionMechanismTypes
785
+ ] = DEFAULT_DETECTION_MECHANISM,
786
+ created_by: Optional[CorpUserUrn] = None,
787
+ created_at: Union[datetime, None] = None,
788
+ updated_by: Optional[CorpUserUrn] = None,
789
+ updated_at: Optional[datetime] = None,
790
+ ):
791
+ """
792
+ Initialize a freshness assertion.
793
+
794
+ Note: Values can be accessed, but not set on the assertion object.
795
+ To update an assertion, use the `upsert_*` method.
796
+ Args:
797
+ urn: The urn of the assertion.
798
+ dataset_urn: The urn of the dataset that the assertion is for.
799
+ display_name: The display name of the assertion.
800
+ mode: The mode of the assertion (active, inactive).
801
+ schedule: The schedule of the assertion.
802
+ freshness_schedule_check_type: The type of freshness schedule check to be used for the assertion.
803
+ lookback_window: The lookback window to be used for the assertion.
804
+ tags: The tags applied to the assertion.
805
+ incident_behavior: Whether to raise or resolve an incident when the assertion fails / passes.
806
+ detection_mechanism: The detection mechanism of the assertion.
807
+ created_by: The urn of the user that created the assertion.
808
+ created_at: The timestamp of when the assertion was created.
809
+ updated_by: The urn of the user that updated the assertion.
810
+ updated_at: The timestamp of when the assertion was updated.
811
+ """
812
+ _HasSchedule.__init__(self, schedule=schedule)
813
+ _AssertionPublic.__init__(
814
+ self,
815
+ urn=urn,
816
+ dataset_urn=dataset_urn,
817
+ display_name=display_name,
818
+ mode=mode,
819
+ incident_behavior=incident_behavior,
820
+ detection_mechanism=detection_mechanism,
821
+ created_by=created_by,
822
+ created_at=created_at,
823
+ updated_by=updated_by,
824
+ updated_at=updated_at,
825
+ tags=tags,
826
+ )
827
+ self._freshness_schedule_check_type = freshness_schedule_check_type
828
+ self._lookback_window = lookback_window
829
+
830
+ @property
831
+ def freshness_schedule_check_type(
832
+ self,
833
+ ) -> Union[str, models.FreshnessAssertionScheduleTypeClass]:
834
+ return self._freshness_schedule_check_type
835
+
836
+ @property
837
+ def lookback_window(self) -> Optional[TimeWindowSizeInputTypes]:
838
+ return self._lookback_window
839
+
840
+ @staticmethod
841
+ def _get_freshness_schedule_check_type(
842
+ assertion: Assertion,
843
+ ) -> Union[str, models.FreshnessAssertionScheduleTypeClass]:
844
+ if assertion.info is None:
845
+ raise SDKNotYetSupportedError(
846
+ f"Assertion {assertion.urn} does not have a freshness assertion info, which is not supported"
847
+ )
848
+ if isinstance(assertion.info, models.FreshnessAssertionInfoClass):
849
+ if assertion.info.schedule is None:
850
+ raise SDKNotYetSupportedError(
851
+ f"Traditional freshness assertion {assertion.urn} does not have a schedule, which is not supported"
852
+ )
853
+ return assertion.info.schedule.type
854
+ else:
855
+ raise SDKNotYetSupportedError(
856
+ f"Assertion {assertion.urn} is not a freshness assertion"
857
+ )
858
+
859
+ @staticmethod
860
+ def _get_lookback_window(
861
+ assertion: Assertion,
862
+ ) -> Optional[models.FixedIntervalScheduleClass]:
863
+ if assertion.info is None:
864
+ raise SDKNotYetSupportedError(
865
+ f"Assertion {assertion.urn} does not have a freshness assertion info, which is not supported"
866
+ )
867
+ if isinstance(assertion.info, models.FreshnessAssertionInfoClass):
868
+ if assertion.info.schedule is None:
869
+ raise SDKNotYetSupportedError(
870
+ f"Traditional freshness assertion {assertion.urn} does not have a schedule, which is not supported"
871
+ )
872
+ return assertion.info.schedule.fixedInterval
873
+ else:
874
+ raise SDKNotYetSupportedError(
875
+ f"Assertion {assertion.urn} is not a freshness assertion"
876
+ )
877
+
878
+ @classmethod
879
+ def _from_entities(cls, assertion: Assertion, monitor: Monitor) -> Self:
880
+ """
881
+ Create a freshness assertion from the assertion and monitor entities.
882
+ """
883
+ return cls(
884
+ urn=assertion.urn,
885
+ dataset_urn=assertion.dataset,
886
+ display_name=assertion.description or "",
887
+ mode=cls._get_mode(monitor),
888
+ schedule=cls._get_schedule(monitor),
889
+ freshness_schedule_check_type=cls._get_freshness_schedule_check_type(
890
+ assertion
891
+ ),
892
+ lookback_window=cls._get_lookback_window(assertion),
893
+ incident_behavior=cls._get_incident_behavior(assertion),
894
+ detection_mechanism=cls._get_detection_mechanism(assertion, monitor),
895
+ created_by=cls._get_created_by(assertion),
896
+ created_at=cls._get_created_at(assertion),
897
+ updated_by=cls._get_updated_by(assertion),
898
+ updated_at=cls._get_updated_at(assertion),
899
+ tags=cls._get_tags(assertion),
900
+ )
901
+
902
+
903
+ class SmartColumnMetricAssertion(_HasSmartFunctionality, _AssertionPublic):
904
+ """
905
+ A class that represents a smart column metric assertion.
906
+ """
907
+
908
+ def __init__(self) -> None:
909
+ raise NotImplementedError("SmartColumnMetricAssertion is not implemented yet")
910
+
911
+
763
912
  AssertionTypes = Union[
764
913
  SmartFreshnessAssertion,
765
914
  SmartVolumeAssertion,
915
+ FreshnessAssertion,
916
+ SmartColumnMetricAssertion,
766
917
  # TODO: Add other assertion types here as we add them.
767
918
  ]
File without changes