acryl-datahub-cloud 0.3.12.4rc2__py3-none-any.whl → 0.3.13__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.

Files changed (53) hide show
  1. acryl_datahub_cloud/_codegen_config.json +1 -1
  2. acryl_datahub_cloud/lineage_features/source.py +8 -2
  3. acryl_datahub_cloud/metadata/_urns/urn_defs.py +168 -0
  4. acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/actionworkflow/__init__.py +53 -0
  5. acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/assertion/__init__.py +2 -0
  6. acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/identity/__init__.py +2 -0
  7. acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/logical/__init__.py +15 -0
  8. acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/metadata/key/__init__.py +6 -0
  9. acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/module/__init__.py +31 -0
  10. acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/settings/global/__init__.py +4 -0
  11. acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/template/__init__.py +25 -0
  12. acryl_datahub_cloud/metadata/schema.avsc +1543 -275
  13. acryl_datahub_cloud/metadata/schema_classes.py +2040 -4
  14. acryl_datahub_cloud/metadata/schemas/ActionRequestInfo.avsc +136 -1
  15. acryl_datahub_cloud/metadata/schemas/ActionWorkflowInfo.avsc +683 -0
  16. acryl_datahub_cloud/metadata/schemas/ActionWorkflowKey.avsc +21 -0
  17. acryl_datahub_cloud/metadata/schemas/AssertionAnalyticsRunEvent.avsc +46 -0
  18. acryl_datahub_cloud/metadata/schemas/AssertionInfo.avsc +25 -0
  19. acryl_datahub_cloud/metadata/schemas/AssertionRunEvent.avsc +25 -0
  20. acryl_datahub_cloud/metadata/schemas/CorpUserSettings.avsc +50 -0
  21. acryl_datahub_cloud/metadata/schemas/DataHubPageModuleKey.avsc +21 -0
  22. acryl_datahub_cloud/metadata/schemas/DataHubPageModuleProperties.avsc +281 -0
  23. acryl_datahub_cloud/metadata/schemas/DataHubPageTemplateKey.avsc +21 -0
  24. acryl_datahub_cloud/metadata/schemas/DataHubPageTemplateProperties.avsc +175 -0
  25. acryl_datahub_cloud/metadata/schemas/DataJobInputOutput.avsc +8 -0
  26. acryl_datahub_cloud/metadata/schemas/DatasetKey.avsc +1 -0
  27. acryl_datahub_cloud/metadata/schemas/GlobalSettingsInfo.avsc +71 -0
  28. acryl_datahub_cloud/metadata/schemas/LogicalParent.avsc +140 -0
  29. acryl_datahub_cloud/metadata/schemas/MetadataChangeEvent.avsc +163 -1
  30. acryl_datahub_cloud/metadata/schemas/MetadataChangeLog.avsc +62 -44
  31. acryl_datahub_cloud/metadata/schemas/MetadataChangeProposal.avsc +61 -0
  32. acryl_datahub_cloud/metadata/schemas/MonitorInfo.avsc +25 -0
  33. acryl_datahub_cloud/metadata/schemas/NotificationRequest.avsc +4 -0
  34. acryl_datahub_cloud/metadata/schemas/QuerySubjects.avsc +1 -12
  35. acryl_datahub_cloud/metadata/schemas/SchemaFieldKey.avsc +1 -0
  36. acryl_datahub_cloud/metadata/schemas/SystemMetadata.avsc +61 -0
  37. acryl_datahub_cloud/metadata/schemas/UpstreamLineage.avsc +9 -0
  38. acryl_datahub_cloud/sdk/assertion/__init__.py +49 -0
  39. acryl_datahub_cloud/sdk/assertion/assertion_base.py +65 -806
  40. acryl_datahub_cloud/sdk/assertion/freshness_assertion.py +201 -0
  41. acryl_datahub_cloud/sdk/assertion/smart_freshness_assertion.py +165 -0
  42. acryl_datahub_cloud/sdk/assertion/smart_volume_assertion.py +162 -0
  43. acryl_datahub_cloud/sdk/assertion/sql_assertion.py +256 -0
  44. acryl_datahub_cloud/sdk/assertion/volume_assertion.py +156 -0
  45. acryl_datahub_cloud/sdk/assertion_input/assertion_input.py +0 -344
  46. acryl_datahub_cloud/sdk/assertion_input/smart_freshness_assertion_input.py +220 -0
  47. acryl_datahub_cloud/sdk/assertion_input/smart_volume_assertion_input.py +191 -0
  48. acryl_datahub_cloud/sdk/assertions_client.py +6 -2
  49. {acryl_datahub_cloud-0.3.12.4rc2.dist-info → acryl_datahub_cloud-0.3.13.dist-info}/METADATA +46 -44
  50. {acryl_datahub_cloud-0.3.12.4rc2.dist-info → acryl_datahub_cloud-0.3.13.dist-info}/RECORD +53 -35
  51. {acryl_datahub_cloud-0.3.12.4rc2.dist-info → acryl_datahub_cloud-0.3.13.dist-info}/WHEEL +0 -0
  52. {acryl_datahub_cloud-0.3.12.4rc2.dist-info → acryl_datahub_cloud-0.3.13.dist-info}/entry_points.txt +0 -0
  53. {acryl_datahub_cloud-0.3.12.4rc2.dist-info → acryl_datahub_cloud-0.3.13.dist-info}/top_level.txt +0 -0
@@ -26,7 +26,6 @@ from acryl_datahub_cloud.sdk.entities.assertion import (
26
26
  )
27
27
  from acryl_datahub_cloud.sdk.entities.monitor import Monitor
28
28
  from acryl_datahub_cloud.sdk.errors import (
29
- SDKNotYetSupportedError,
30
29
  SDKUsageError,
31
30
  SDKUsageErrorWithExamples,
32
31
  )
@@ -1383,346 +1382,3 @@ class _HasFreshnessFeatures:
1383
1382
  nativeType=field_spec.nativeType,
1384
1383
  kind=kind,
1385
1384
  )
1386
-
1387
-
1388
- class _SmartFreshnessAssertionInput(
1389
- _AssertionInput, _HasSmartAssertionInputs, _HasFreshnessFeatures
1390
- ):
1391
- def __init__(
1392
- self,
1393
- *,
1394
- # Required fields
1395
- dataset_urn: Union[str, DatasetUrn],
1396
- entity_client: EntityClient, # Needed to get the schema field spec for the detection mechanism if needed
1397
- # Optional fields
1398
- urn: Optional[Union[str, AssertionUrn]] = None,
1399
- display_name: Optional[str] = None,
1400
- enabled: bool = True,
1401
- schedule: Optional[Union[str, models.CronScheduleClass]] = None,
1402
- detection_mechanism: DetectionMechanismInputTypes = None,
1403
- sensitivity: Optional[Union[str, InferenceSensitivity]] = None,
1404
- exclusion_windows: Optional[ExclusionWindowInputTypes] = None,
1405
- training_data_lookback_days: Optional[int] = None,
1406
- incident_behavior: Optional[AssertionIncidentBehaviorInputTypes] = None,
1407
- tags: Optional[TagsInputType] = None,
1408
- created_by: Union[str, CorpUserUrn],
1409
- created_at: datetime,
1410
- updated_by: Union[str, CorpUserUrn],
1411
- updated_at: datetime,
1412
- ):
1413
- _AssertionInput.__init__(
1414
- self,
1415
- dataset_urn=dataset_urn,
1416
- entity_client=entity_client,
1417
- urn=urn,
1418
- display_name=display_name,
1419
- enabled=enabled,
1420
- schedule=schedule
1421
- if schedule is not None
1422
- else DEFAULT_HOURLY_SCHEDULE, # Use provided schedule or default for create case
1423
- detection_mechanism=detection_mechanism,
1424
- incident_behavior=incident_behavior,
1425
- tags=tags,
1426
- source_type=models.AssertionSourceTypeClass.INFERRED, # Smart assertions are of type inferred, not native
1427
- created_by=created_by,
1428
- created_at=created_at,
1429
- updated_by=updated_by,
1430
- updated_at=updated_at,
1431
- )
1432
- _HasSmartAssertionInputs.__init__(
1433
- self,
1434
- sensitivity=sensitivity,
1435
- exclusion_windows=exclusion_windows,
1436
- training_data_lookback_days=training_data_lookback_days,
1437
- )
1438
-
1439
- def _assertion_type(self) -> str:
1440
- """Get the assertion type."""
1441
- return models.AssertionTypeClass.FRESHNESS
1442
-
1443
- def _create_assertion_info(
1444
- self, filter: Optional[models.DatasetFilterClass]
1445
- ) -> AssertionInfoInputType:
1446
- """
1447
- Create a FreshnessAssertionInfoClass for a smart freshness assertion.
1448
-
1449
- Args:
1450
- filter: Optional filter to apply to the assertion.
1451
-
1452
- Returns:
1453
- A FreshnessAssertionInfoClass configured for smart freshness.
1454
- """
1455
- return models.FreshnessAssertionInfoClass(
1456
- type=models.FreshnessAssertionTypeClass.DATASET_CHANGE, # Currently only dataset change is supported
1457
- entity=str(self.dataset_urn),
1458
- # schedule (optional, must be left empty for smart freshness assertions - managed by the AI inference engine)
1459
- filter=filter,
1460
- )
1461
-
1462
- def _convert_schedule(self) -> models.CronScheduleClass:
1463
- """Create a schedule for a smart freshness assertion.
1464
-
1465
- For create case, uses DEFAULT_HOURLY_SCHEDULE. For update case, preserves existing schedule.
1466
-
1467
- Returns:
1468
- A CronScheduleClass with appropriate schedule settings.
1469
- """
1470
- assert self.schedule is not None, (
1471
- "Schedule should never be None due to constructor logic"
1472
- )
1473
- return self.schedule
1474
-
1475
- def _get_assertion_evaluation_parameters(
1476
- self, source_type: str, field: Optional[FieldSpecType]
1477
- ) -> models.AssertionEvaluationParametersClass:
1478
- # Ensure field is either None or FreshnessFieldSpecClass
1479
- freshness_field = None
1480
- if field is not None:
1481
- if not isinstance(field, models.FreshnessFieldSpecClass):
1482
- raise SDKUsageError(
1483
- f"Expected FreshnessFieldSpecClass for freshness assertion, got {type(field).__name__}"
1484
- )
1485
- freshness_field = field
1486
-
1487
- return models.AssertionEvaluationParametersClass(
1488
- type=models.AssertionEvaluationParametersTypeClass.DATASET_FRESHNESS,
1489
- datasetFreshnessParameters=models.DatasetFreshnessAssertionParametersClass(
1490
- sourceType=source_type, field=freshness_field
1491
- ),
1492
- )
1493
-
1494
- def _convert_assertion_source_type_and_field(
1495
- self,
1496
- ) -> tuple[str, Optional[FieldSpecType]]:
1497
- """
1498
- Convert detection mechanism into source type and field specification for freshness assertions.
1499
-
1500
- Returns:
1501
- A tuple of (source_type, field) where field may be None.
1502
- Note that the source_type is a string, not a models.DatasetFreshnessSourceTypeClass (or other assertion source type) since
1503
- the source type is not a enum in the code generated from the DatasetFreshnessSourceType enum in the PDL.
1504
-
1505
- Raises:
1506
- SDKNotYetSupportedError: If the detection mechanism is not supported.
1507
- SDKUsageError: If the field (column) is not found in the dataset,
1508
- and the detection mechanism requires a field. Also if the field
1509
- is not an allowed type for the detection mechanism.
1510
- """
1511
- source_type = models.DatasetFreshnessSourceTypeClass.INFORMATION_SCHEMA
1512
- field = None
1513
-
1514
- if isinstance(self.detection_mechanism, _LastModifiedColumn):
1515
- source_type = models.DatasetFreshnessSourceTypeClass.FIELD_VALUE
1516
- field = self._create_field_spec(
1517
- self.detection_mechanism.column_name,
1518
- LAST_MODIFIED_ALLOWED_FIELD_TYPES,
1519
- "last modified column",
1520
- models.FreshnessFieldKindClass.LAST_MODIFIED,
1521
- self._get_schema_field_spec,
1522
- self._validate_field_type,
1523
- )
1524
- elif isinstance(self.detection_mechanism, _InformationSchema):
1525
- source_type = models.DatasetFreshnessSourceTypeClass.INFORMATION_SCHEMA
1526
- elif isinstance(self.detection_mechanism, _DataHubOperation):
1527
- source_type = models.DatasetFreshnessSourceTypeClass.DATAHUB_OPERATION
1528
- elif isinstance(self.detection_mechanism, _AuditLog):
1529
- source_type = models.DatasetFreshnessSourceTypeClass.AUDIT_LOG
1530
- else:
1531
- raise SDKNotYetSupportedError(
1532
- f"Detection mechanism {self.detection_mechanism} not yet supported for smart freshness assertions"
1533
- )
1534
-
1535
- return source_type, field
1536
-
1537
- def _create_monitor_info(
1538
- self,
1539
- assertion_urn: AssertionUrn,
1540
- status: models.MonitorStatusClass,
1541
- schedule: models.CronScheduleClass,
1542
- ) -> models.MonitorInfoClass:
1543
- """
1544
- Create a MonitorInfoClass with all the necessary components.
1545
- """
1546
- source_type, field = self._convert_assertion_source_type_and_field()
1547
- return models.MonitorInfoClass(
1548
- type=models.MonitorTypeClass.ASSERTION,
1549
- status=status,
1550
- assertionMonitor=models.AssertionMonitorClass(
1551
- assertions=[
1552
- models.AssertionEvaluationSpecClass(
1553
- assertion=str(assertion_urn),
1554
- schedule=schedule,
1555
- parameters=self._get_assertion_evaluation_parameters(
1556
- str(source_type), field
1557
- ),
1558
- ),
1559
- ],
1560
- settings=models.AssertionMonitorSettingsClass(
1561
- adjustmentSettings=models.AssertionAdjustmentSettingsClass(
1562
- sensitivity=self._convert_sensitivity(),
1563
- exclusionWindows=self._convert_exclusion_windows(),
1564
- trainingDataLookbackWindowDays=self.training_data_lookback_days,
1565
- ),
1566
- ),
1567
- ),
1568
- )
1569
-
1570
-
1571
- class _SmartVolumeAssertionInput(_AssertionInput, _HasSmartAssertionInputs):
1572
- def __init__(
1573
- self,
1574
- *,
1575
- # Required fields
1576
- dataset_urn: Union[str, DatasetUrn],
1577
- entity_client: EntityClient, # Needed to get the schema field spec for the detection mechanism if needed
1578
- # Optional fields
1579
- urn: Optional[Union[str, AssertionUrn]] = None,
1580
- display_name: Optional[str] = None,
1581
- enabled: bool = True,
1582
- schedule: Optional[Union[str, models.CronScheduleClass]] = None,
1583
- detection_mechanism: DetectionMechanismInputTypes = None,
1584
- sensitivity: Optional[Union[str, InferenceSensitivity]] = None,
1585
- exclusion_windows: Optional[ExclusionWindowInputTypes] = None,
1586
- training_data_lookback_days: Optional[int] = None,
1587
- incident_behavior: Optional[AssertionIncidentBehaviorInputTypes] = None,
1588
- tags: Optional[TagsInputType] = None,
1589
- created_by: Union[str, CorpUserUrn],
1590
- created_at: datetime,
1591
- updated_by: Union[str, CorpUserUrn],
1592
- updated_at: datetime,
1593
- ):
1594
- _AssertionInput.__init__(
1595
- self,
1596
- dataset_urn=dataset_urn,
1597
- entity_client=entity_client,
1598
- urn=urn,
1599
- display_name=display_name,
1600
- enabled=enabled,
1601
- schedule=schedule,
1602
- detection_mechanism=detection_mechanism,
1603
- incident_behavior=incident_behavior,
1604
- tags=tags,
1605
- source_type=models.AssertionSourceTypeClass.INFERRED, # Smart assertions are of type inferred, not native
1606
- created_by=created_by,
1607
- created_at=created_at,
1608
- updated_by=updated_by,
1609
- updated_at=updated_at,
1610
- )
1611
- _HasSmartAssertionInputs.__init__(
1612
- self,
1613
- sensitivity=sensitivity,
1614
- exclusion_windows=exclusion_windows,
1615
- training_data_lookback_days=training_data_lookback_days,
1616
- )
1617
-
1618
- def _create_assertion_info(
1619
- self, filter: Optional[models.DatasetFilterClass]
1620
- ) -> AssertionInfoInputType:
1621
- """
1622
- Create a VolumeAssertionInfoClass for a smart volume assertion.
1623
-
1624
- Args:
1625
- filter: Optional filter to apply to the assertion.
1626
-
1627
- Returns:
1628
- A VolumeAssertionInfoClass configured for smart volume.
1629
- """
1630
- return models.VolumeAssertionInfoClass(
1631
- type=models.VolumeAssertionTypeClass.ROW_COUNT_TOTAL, # Currently only ROW_COUNT_TOTAL is supported for smart volume
1632
- entity=str(self.dataset_urn),
1633
- filter=filter,
1634
- )
1635
-
1636
- def _convert_schedule(self) -> models.CronScheduleClass:
1637
- """Create a schedule for a smart volume assertion.
1638
-
1639
- Returns:
1640
- A CronScheduleClass with appropriate schedule settings.
1641
- """
1642
- if self.schedule is None:
1643
- return DEFAULT_HOURLY_SCHEDULE
1644
-
1645
- return models.CronScheduleClass(
1646
- cron=self.schedule.cron,
1647
- timezone=self.schedule.timezone,
1648
- )
1649
-
1650
- def _get_assertion_evaluation_parameters(
1651
- self, source_type: str, field: Optional[FieldSpecType]
1652
- ) -> models.AssertionEvaluationParametersClass:
1653
- return models.AssertionEvaluationParametersClass(
1654
- type=models.AssertionEvaluationParametersTypeClass.DATASET_VOLUME,
1655
- datasetVolumeParameters=models.DatasetVolumeAssertionParametersClass(
1656
- sourceType=source_type,
1657
- ),
1658
- )
1659
-
1660
- def _convert_assertion_source_type_and_field(
1661
- self,
1662
- ) -> tuple[str, Optional[FieldSpecType]]:
1663
- """
1664
- Convert detection mechanism into source type and field specification for volume assertions.
1665
-
1666
- Returns:
1667
- A tuple of (source_type, field) where field may be None.
1668
- Note that the source_type is a string, not a models.DatasetFreshnessSourceTypeClass (or other assertion source type) since
1669
- the source type is not a enum in the code generated from the DatasetFreshnessSourceType enum in the PDL.
1670
-
1671
- Raises:
1672
- SDKNotYetSupportedError: If the detection mechanism is not supported.
1673
- SDKUsageError: If the field (column) is not found in the dataset,
1674
- and the detection mechanism requires a field. Also if the field
1675
- is not an allowed type for the detection mechanism.
1676
- """
1677
- source_type = models.DatasetVolumeSourceTypeClass.INFORMATION_SCHEMA
1678
- field = None
1679
-
1680
- if isinstance(self.detection_mechanism, _Query):
1681
- source_type = models.DatasetVolumeSourceTypeClass.QUERY
1682
- elif isinstance(self.detection_mechanism, _InformationSchema):
1683
- source_type = models.DatasetVolumeSourceTypeClass.INFORMATION_SCHEMA
1684
- elif isinstance(self.detection_mechanism, _DatasetProfile):
1685
- source_type = models.DatasetVolumeSourceTypeClass.DATAHUB_DATASET_PROFILE
1686
- else:
1687
- raise SDKNotYetSupportedError(
1688
- f"Detection mechanism {self.detection_mechanism} not yet supported for smart volume assertions"
1689
- )
1690
-
1691
- return source_type, field
1692
-
1693
- def _create_monitor_info(
1694
- self,
1695
- assertion_urn: AssertionUrn,
1696
- status: models.MonitorStatusClass,
1697
- schedule: models.CronScheduleClass,
1698
- ) -> models.MonitorInfoClass:
1699
- """
1700
- Create a MonitorInfoClass with all the necessary components.
1701
- """
1702
- source_type, field = self._convert_assertion_source_type_and_field()
1703
- return models.MonitorInfoClass(
1704
- type=models.MonitorTypeClass.ASSERTION,
1705
- status=status,
1706
- assertionMonitor=models.AssertionMonitorClass(
1707
- assertions=[
1708
- models.AssertionEvaluationSpecClass(
1709
- assertion=str(assertion_urn),
1710
- schedule=schedule,
1711
- parameters=self._get_assertion_evaluation_parameters(
1712
- str(source_type), field
1713
- ),
1714
- ),
1715
- ],
1716
- settings=models.AssertionMonitorSettingsClass(
1717
- adjustmentSettings=models.AssertionAdjustmentSettingsClass(
1718
- sensitivity=self._convert_sensitivity(),
1719
- exclusionWindows=self._convert_exclusion_windows(),
1720
- trainingDataLookbackWindowDays=self.training_data_lookback_days,
1721
- ),
1722
- ),
1723
- ),
1724
- )
1725
-
1726
- def _assertion_type(self) -> str:
1727
- """Get the assertion type."""
1728
- return models.AssertionTypeClass.VOLUME
@@ -0,0 +1,220 @@
1
+ """
2
+ Smart Freshness Assertion Input classes for DataHub.
3
+
4
+ This module contains the _SmartFreshnessAssertionInput class that handles
5
+ input validation and entity creation for smart freshness assertions.
6
+ """
7
+
8
+ from datetime import datetime
9
+ from typing import Optional, Union
10
+
11
+ from acryl_datahub_cloud.sdk.assertion_input.assertion_input import (
12
+ DEFAULT_HOURLY_SCHEDULE,
13
+ LAST_MODIFIED_ALLOWED_FIELD_TYPES,
14
+ AssertionIncidentBehaviorInputTypes,
15
+ DetectionMechanismInputTypes,
16
+ ExclusionWindowInputTypes,
17
+ FieldSpecType,
18
+ InferenceSensitivity,
19
+ _AssertionInput,
20
+ _AuditLog,
21
+ _DataHubOperation,
22
+ _HasFreshnessFeatures,
23
+ _HasSmartAssertionInputs,
24
+ _InformationSchema,
25
+ _LastModifiedColumn,
26
+ )
27
+ from acryl_datahub_cloud.sdk.entities.assertion import (
28
+ AssertionInfoInputType,
29
+ TagsInputType,
30
+ )
31
+ from acryl_datahub_cloud.sdk.errors import (
32
+ SDKNotYetSupportedError,
33
+ SDKUsageError,
34
+ )
35
+ from datahub.metadata import schema_classes as models
36
+ from datahub.metadata.urns import AssertionUrn, CorpUserUrn, DatasetUrn
37
+ from datahub.sdk.entity_client import EntityClient
38
+
39
+
40
+ class _SmartFreshnessAssertionInput(
41
+ _AssertionInput, _HasSmartAssertionInputs, _HasFreshnessFeatures
42
+ ):
43
+ def __init__(
44
+ self,
45
+ *,
46
+ # Required fields
47
+ dataset_urn: Union[str, DatasetUrn],
48
+ entity_client: EntityClient, # Needed to get the schema field spec for the detection mechanism if needed
49
+ # Optional fields
50
+ urn: Optional[Union[str, AssertionUrn]] = None,
51
+ display_name: Optional[str] = None,
52
+ enabled: bool = True,
53
+ schedule: Optional[Union[str, models.CronScheduleClass]] = None,
54
+ detection_mechanism: DetectionMechanismInputTypes = None,
55
+ sensitivity: Optional[Union[str, InferenceSensitivity]] = None,
56
+ exclusion_windows: Optional[ExclusionWindowInputTypes] = None,
57
+ training_data_lookback_days: Optional[int] = None,
58
+ incident_behavior: Optional[AssertionIncidentBehaviorInputTypes] = None,
59
+ tags: Optional[TagsInputType] = None,
60
+ created_by: Union[str, CorpUserUrn],
61
+ created_at: datetime,
62
+ updated_by: Union[str, CorpUserUrn],
63
+ updated_at: datetime,
64
+ ):
65
+ _AssertionInput.__init__(
66
+ self,
67
+ dataset_urn=dataset_urn,
68
+ entity_client=entity_client,
69
+ urn=urn,
70
+ display_name=display_name,
71
+ enabled=enabled,
72
+ schedule=schedule
73
+ if schedule is not None
74
+ else DEFAULT_HOURLY_SCHEDULE, # Use provided schedule or default for create case
75
+ detection_mechanism=detection_mechanism,
76
+ incident_behavior=incident_behavior,
77
+ tags=tags,
78
+ source_type=models.AssertionSourceTypeClass.INFERRED, # Smart assertions are of type inferred, not native
79
+ created_by=created_by,
80
+ created_at=created_at,
81
+ updated_by=updated_by,
82
+ updated_at=updated_at,
83
+ )
84
+ _HasSmartAssertionInputs.__init__(
85
+ self,
86
+ sensitivity=sensitivity,
87
+ exclusion_windows=exclusion_windows,
88
+ training_data_lookback_days=training_data_lookback_days,
89
+ )
90
+
91
+ def _assertion_type(self) -> str:
92
+ """Get the assertion type."""
93
+ return models.AssertionTypeClass.FRESHNESS
94
+
95
+ def _create_assertion_info(
96
+ self, filter: Optional[models.DatasetFilterClass]
97
+ ) -> AssertionInfoInputType:
98
+ """
99
+ Create a FreshnessAssertionInfoClass for a smart freshness assertion.
100
+
101
+ Args:
102
+ filter: Optional filter to apply to the assertion.
103
+
104
+ Returns:
105
+ A FreshnessAssertionInfoClass configured for smart freshness.
106
+ """
107
+ return models.FreshnessAssertionInfoClass(
108
+ type=models.FreshnessAssertionTypeClass.DATASET_CHANGE, # Currently only dataset change is supported
109
+ entity=str(self.dataset_urn),
110
+ # schedule (optional, must be left empty for smart freshness assertions - managed by the AI inference engine)
111
+ filter=filter,
112
+ )
113
+
114
+ def _convert_schedule(self) -> models.CronScheduleClass:
115
+ """Create a schedule for a smart freshness assertion.
116
+
117
+ For create case, uses DEFAULT_HOURLY_SCHEDULE. For update case, preserves existing schedule.
118
+
119
+ Returns:
120
+ A CronScheduleClass with appropriate schedule settings.
121
+ """
122
+ assert self.schedule is not None, (
123
+ "Schedule should never be None due to constructor logic"
124
+ )
125
+ return self.schedule
126
+
127
+ def _get_assertion_evaluation_parameters(
128
+ self, source_type: str, field: Optional[FieldSpecType]
129
+ ) -> models.AssertionEvaluationParametersClass:
130
+ # Ensure field is either None or FreshnessFieldSpecClass
131
+ freshness_field = None
132
+ if field is not None:
133
+ if not isinstance(field, models.FreshnessFieldSpecClass):
134
+ raise SDKUsageError(
135
+ f"Expected FreshnessFieldSpecClass for freshness assertion, got {type(field).__name__}"
136
+ )
137
+ freshness_field = field
138
+
139
+ return models.AssertionEvaluationParametersClass(
140
+ type=models.AssertionEvaluationParametersTypeClass.DATASET_FRESHNESS,
141
+ datasetFreshnessParameters=models.DatasetFreshnessAssertionParametersClass(
142
+ sourceType=source_type, field=freshness_field
143
+ ),
144
+ )
145
+
146
+ def _convert_assertion_source_type_and_field(
147
+ self,
148
+ ) -> tuple[str, Optional[FieldSpecType]]:
149
+ """
150
+ Convert detection mechanism into source type and field specification for freshness assertions.
151
+
152
+ Returns:
153
+ A tuple of (source_type, field) where field may be None.
154
+ Note that the source_type is a string, not a models.DatasetFreshnessSourceTypeClass (or other assertion source type) since
155
+ the source type is not a enum in the code generated from the DatasetFreshnessSourceType enum in the PDL.
156
+
157
+ Raises:
158
+ SDKNotYetSupportedError: If the detection mechanism is not supported.
159
+ SDKUsageError: If the field (column) is not found in the dataset,
160
+ and the detection mechanism requires a field. Also if the field
161
+ is not an allowed type for the detection mechanism.
162
+ """
163
+ source_type = models.DatasetFreshnessSourceTypeClass.INFORMATION_SCHEMA
164
+ field = None
165
+
166
+ if isinstance(self.detection_mechanism, _LastModifiedColumn):
167
+ source_type = models.DatasetFreshnessSourceTypeClass.FIELD_VALUE
168
+ field = self._create_field_spec(
169
+ self.detection_mechanism.column_name,
170
+ LAST_MODIFIED_ALLOWED_FIELD_TYPES,
171
+ "last modified column",
172
+ models.FreshnessFieldKindClass.LAST_MODIFIED,
173
+ self._get_schema_field_spec,
174
+ self._validate_field_type,
175
+ )
176
+ elif isinstance(self.detection_mechanism, _InformationSchema):
177
+ source_type = models.DatasetFreshnessSourceTypeClass.INFORMATION_SCHEMA
178
+ elif isinstance(self.detection_mechanism, _DataHubOperation):
179
+ source_type = models.DatasetFreshnessSourceTypeClass.DATAHUB_OPERATION
180
+ elif isinstance(self.detection_mechanism, _AuditLog):
181
+ source_type = models.DatasetFreshnessSourceTypeClass.AUDIT_LOG
182
+ else:
183
+ raise SDKNotYetSupportedError(
184
+ f"Detection mechanism {self.detection_mechanism} not yet supported for smart freshness assertions"
185
+ )
186
+
187
+ return source_type, field
188
+
189
+ def _create_monitor_info(
190
+ self,
191
+ assertion_urn: AssertionUrn,
192
+ status: models.MonitorStatusClass,
193
+ schedule: models.CronScheduleClass,
194
+ ) -> models.MonitorInfoClass:
195
+ """
196
+ Create a MonitorInfoClass with all the necessary components.
197
+ """
198
+ source_type, field = self._convert_assertion_source_type_and_field()
199
+ return models.MonitorInfoClass(
200
+ type=models.MonitorTypeClass.ASSERTION,
201
+ status=status,
202
+ assertionMonitor=models.AssertionMonitorClass(
203
+ assertions=[
204
+ models.AssertionEvaluationSpecClass(
205
+ assertion=str(assertion_urn),
206
+ schedule=schedule,
207
+ parameters=self._get_assertion_evaluation_parameters(
208
+ str(source_type), field
209
+ ),
210
+ ),
211
+ ],
212
+ settings=models.AssertionMonitorSettingsClass(
213
+ adjustmentSettings=models.AssertionAdjustmentSettingsClass(
214
+ sensitivity=self._convert_sensitivity(),
215
+ exclusionWindows=self._convert_exclusion_windows(),
216
+ trainingDataLookbackWindowDays=self.training_data_lookback_days,
217
+ ),
218
+ ),
219
+ ),
220
+ )