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

@@ -39,13 +39,20 @@ from acryl_datahub_cloud.sdk.assertion_input.smart_column_metric_assertion_input
39
39
  _SmartColumnMetricAssertionInput,
40
40
  )
41
41
  from acryl_datahub_cloud.sdk.assertion_input.sql_assertion_input import (
42
+ SqlAssertionChangeType,
42
43
  SqlAssertionCriteria,
44
+ SqlAssertionOperator,
45
+ SqlAssertionType,
43
46
  _SqlAssertionInput,
44
47
  )
45
48
  from acryl_datahub_cloud.sdk.assertion_input.volume_assertion_input import (
49
+ RowCountChange,
46
50
  RowCountTotal,
47
51
  VolumeAssertionDefinition,
52
+ VolumeAssertionDefinitionChangeKind,
48
53
  VolumeAssertionDefinitionInputTypes,
54
+ VolumeAssertionDefinitionParameters,
55
+ VolumeAssertionDefinitionType,
49
56
  VolumeAssertionOperator,
50
57
  _VolumeAssertionDefinitionTypes,
51
58
  _VolumeAssertionInput,
@@ -518,7 +525,7 @@ class AssertionsClient:
518
525
  updated_by: Optional[Union[str, CorpUserUrn]],
519
526
  now_utc: datetime,
520
527
  schedule: Optional[Union[str, models.CronScheduleClass]],
521
- definition: Optional[VolumeAssertionDefinitionInputTypes],
528
+ definition: VolumeAssertionDefinitionInputTypes,
522
529
  use_backend_definition: bool = False,
523
530
  ) -> Union[VolumeAssertion, _VolumeAssertionInput]:
524
531
  # 1. Retrieve any existing assertion and monitor entities:
@@ -549,6 +556,9 @@ class AssertionsClient:
549
556
  logger.info(
550
557
  f"No existing assertion entity found for assertion urn {urn}, creating a new assertion with a generated urn"
551
558
  )
559
+ # Extract criteria from definition to call the new signature
560
+ parsed_definition = VolumeAssertionDefinition.parse(definition)
561
+ assert isinstance(parsed_definition, (RowCountTotal, RowCountChange))
552
562
  return self._create_volume_assertion(
553
563
  dataset_urn=dataset_urn,
554
564
  display_name=display_name,
@@ -557,7 +567,12 @@ class AssertionsClient:
557
567
  tags=tags,
558
568
  created_by=updated_by,
559
569
  schedule=schedule,
560
- definition=definition,
570
+ criteria_type=parsed_definition.type,
571
+ criteria_change_type=parsed_definition.kind
572
+ if isinstance(parsed_definition, RowCountChange)
573
+ else None,
574
+ criteria_operator=parsed_definition.operator,
575
+ criteria_parameters=parsed_definition.parameters,
561
576
  )
562
577
 
563
578
  # 3. Check for any issues e.g. different dataset urns
@@ -654,7 +669,10 @@ class AssertionsClient:
654
669
  return self._create_sql_assertion(
655
670
  dataset_urn=dataset_urn,
656
671
  display_name=display_name,
657
- criteria=criteria,
672
+ criteria_type=criteria.type,
673
+ criteria_change_type=criteria.change_type,
674
+ criteria_operator=criteria.operator,
675
+ criteria_parameters=criteria.parameters,
658
676
  statement=statement,
659
677
  incident_behavior=incident_behavior,
660
678
  tags=tags,
@@ -1165,7 +1183,7 @@ class AssertionsClient:
1165
1183
  "criteria",
1166
1184
  assertion_input,
1167
1185
  existing_assertion,
1168
- existing_assertion.criteria if existing_assertion else None,
1186
+ existing_assertion._criteria if existing_assertion else None,
1169
1187
  ),
1170
1188
  statement=_merge_field(
1171
1189
  statement,
@@ -1683,7 +1701,12 @@ class AssertionsClient:
1683
1701
  tags: Optional[TagsInputType] = None,
1684
1702
  created_by: Optional[Union[str, CorpUserUrn]] = None,
1685
1703
  schedule: Optional[Union[str, models.CronScheduleClass]] = None,
1686
- definition: Optional[VolumeAssertionDefinitionInputTypes] = None,
1704
+ criteria_type: Union[str, VolumeAssertionDefinitionType],
1705
+ criteria_change_type: Optional[
1706
+ Union[str, VolumeAssertionDefinitionChangeKind]
1707
+ ] = None,
1708
+ criteria_operator: Union[str, VolumeAssertionOperator],
1709
+ criteria_parameters: VolumeAssertionDefinitionParameters,
1687
1710
  ) -> VolumeAssertion:
1688
1711
  """Create a volume assertion.
1689
1712
 
@@ -1723,25 +1746,23 @@ class AssertionsClient:
1723
1746
  The format is a cron expression, e.g. "0 * * * *" for every hour using UTC timezone.
1724
1747
  Alternatively, a models.CronScheduleClass object can be provided with string parameters
1725
1748
  cron and timezone. Use `from datahub.metadata import schema_classes as models` to import the class.
1726
- definition: The volume assertion definition. Must be provided and include type, operator,
1727
- and parameters. Can be provided as:
1728
- - A typed volume assertion object (RowCountTotal or RowCountChange)
1729
- - A dictionary with keys: type, operator, parameters (and kind for row_count_change)
1730
-
1731
- Example dictionary for row count total:
1732
- {
1733
- "type": "row_count_total",
1734
- "operator": "GREATER_THAN_OR_EQUAL_TO",
1735
- "parameters": 100
1736
- }
1737
-
1738
- Example dictionary for row count change:
1739
- {
1740
- "type": "row_count_change",
1741
- "kind": "percent",
1742
- "operator": "BETWEEN",
1743
- "parameters": (10, 50)
1744
- }
1749
+ criteria_type: The type of volume assertion. Must be either VolumeAssertionDefinitionType.ROW_COUNT_TOTAL or VolumeAssertionDefinitionType.ROW_COUNT_CHANGE.
1750
+ Raw string values are also accepted: "ROW_COUNT_TOTAL" or "ROW_COUNT_CHANGE".
1751
+ criteria_change_type: Required when criteria_type is VolumeAssertionDefinitionType.ROW_COUNT_CHANGE. Must be either VolumeAssertionDefinitionChangeKind.ABSOLUTE
1752
+ or VolumeAssertionDefinitionChangeKind.PERCENT. Optional (ignored) when criteria_type is VolumeAssertionDefinitionType.ROW_COUNT_TOTAL.
1753
+ Raw string values are also accepted: "ABSOLUTE" or "PERCENTAGE".
1754
+ criteria_operator: The comparison operator for the assertion. Must be a VolumeAssertionOperator value:
1755
+ - VolumeAssertionOperator.GREATER_THAN_OR_EQUAL_TO
1756
+ - VolumeAssertionOperator.LESS_THAN_OR_EQUAL_TO
1757
+ - VolumeAssertionOperator.BETWEEN
1758
+ Raw string values are also accepted: "GREATER_THAN_OR_EQUAL_TO", "LESS_THAN_OR_EQUAL_TO", "BETWEEN".
1759
+ criteria_parameters: The parameters for the assertion. For single-value operators
1760
+ (GREATER_THAN_OR_EQUAL_TO, LESS_THAN_OR_EQUAL_TO), provide a single number.
1761
+ For BETWEEN operator, provide a tuple of two numbers (min_value, max_value).
1762
+
1763
+ Examples:
1764
+ - For single value: 100 or 50.5
1765
+ - For BETWEEN: (10, 100) or (5.0, 15.5)
1745
1766
 
1746
1767
  Returns:
1747
1768
  VolumeAssertion: The created assertion.
@@ -1753,6 +1774,17 @@ class AssertionsClient:
1753
1774
  f"Created by is not set, using {DEFAULT_CREATED_BY} as a placeholder"
1754
1775
  )
1755
1776
  created_by = DEFAULT_CREATED_BY
1777
+
1778
+ # Create definition from individual criteria parameters
1779
+ # The dictionary object will be fully validated down in the _VolumeAssertionInput class
1780
+ definition: dict[str, Any] = {
1781
+ "type": criteria_type,
1782
+ "operator": criteria_operator,
1783
+ "parameters": criteria_parameters,
1784
+ }
1785
+ if criteria_type == VolumeAssertionDefinitionType.ROW_COUNT_CHANGE:
1786
+ definition["kind"] = criteria_change_type
1787
+
1756
1788
  assertion_input = _VolumeAssertionInput(
1757
1789
  urn=None,
1758
1790
  entity_client=self.client.entities,
@@ -1789,7 +1821,12 @@ class AssertionsClient:
1789
1821
  dataset_urn: Union[str, DatasetUrn],
1790
1822
  display_name: Optional[str] = None,
1791
1823
  enabled: bool = True,
1792
- criteria: SqlAssertionCriteria,
1824
+ criteria_type: Union[SqlAssertionType, str],
1825
+ criteria_change_type: Optional[Union[SqlAssertionChangeType, str]] = None,
1826
+ criteria_operator: Union[SqlAssertionOperator, str],
1827
+ criteria_parameters: Union[
1828
+ Union[float, int], tuple[Union[float, int], Union[float, int]]
1829
+ ],
1793
1830
  statement: str,
1794
1831
  incident_behavior: Optional[
1795
1832
  Union[AssertionIncidentBehavior, list[AssertionIncidentBehavior]]
@@ -1805,25 +1842,23 @@ class AssertionsClient:
1805
1842
  display_name: The display name of the assertion. If not provided, a random display
1806
1843
  name will be generated.
1807
1844
  enabled: Whether the assertion is enabled. Defaults to True.
1808
- criteria: The criteria to be used for the assertion. This is of type SqlAssertionCriteria. It has the following fields:
1809
- - type: The type of sql assertion. Valid values are:
1810
- - "METRIC" -> Looks at the current value of the metric.
1811
- - "METRIC_CHANGE" -> Looks at the change in the metric between the current and previous run.
1812
- - change_type: The change type of the assertion, if the type is "METRIC_CHANGE". Valid values are:
1813
- - "ABSOLUTE" -> Looks at the absolute change in the metric.
1814
- - "PERCENTAGE" -> Looks at the percentage change in the metric.
1815
- - operator: The operator to be used for the assertion. Valid values are:
1816
- - "GREATER_THAN" -> The metric value is greater than the threshold.
1817
- - "LESS_THAN" -> The metric value is less than the threshold.
1818
- - "GREATER_THAN_OR_EQUAL_TO" -> The metric value is greater than or equal to the threshold.
1819
- - "LESS_THAN_OR_EQUAL_TO" -> The metric value is less than or equal to the threshold.
1820
- - "EQUAL_TO" -> The metric value is equal to the threshold.
1821
- - "NOT_EQUAL_TO" -> The metric value is not equal to the threshold.
1822
- - "BETWEEN" -> The metric value is between the two thresholds.
1823
- - parameters: The parameters to be used for the assertion. This is of type SqlAssertionParameters. It has the following fields:
1824
- - value: The value of the metric. This can be a single value or a tuple range.
1825
- - If the operator is "BETWEEN", the value is a tuple of two values, with format min, max.
1826
- - If the operator is not "BETWEEN", the value is a single value.
1845
+ criteria_type: The type of sql assertion. Valid values are:
1846
+ - "METRIC" -> Looks at the current value of the metric.
1847
+ - "METRIC_CHANGE" -> Looks at the change in the metric between the current and previous run.
1848
+ criteria_change_type: The change type of the assertion, if the type is "METRIC_CHANGE". Valid values are:
1849
+ - "ABSOLUTE" -> Looks at the absolute change in the metric.
1850
+ - "PERCENTAGE" -> Looks at the percentage change in the metric.
1851
+ criteria_operator: The operator to be used for the assertion. Valid values are:
1852
+ - "GREATER_THAN" -> The metric value is greater than the threshold.
1853
+ - "LESS_THAN" -> The metric value is less than the threshold.
1854
+ - "GREATER_THAN_OR_EQUAL_TO" -> The metric value is greater than or equal to the threshold.
1855
+ - "LESS_THAN_OR_EQUAL_TO" -> The metric value is less than or equal to the threshold.
1856
+ - "EQUAL_TO" -> The metric value is equal to the threshold.
1857
+ - "NOT_EQUAL_TO" -> The metric value is not equal to the threshold.
1858
+ - "BETWEEN" -> The metric value is between the two thresholds.
1859
+ criteria_parameters: The parameters to be used for the assertion. This can be a single value or a tuple range.
1860
+ - If the operator is "BETWEEN", the value is a tuple of two values, with format min, max.
1861
+ - If the operator is not "BETWEEN", the value is a single value.
1827
1862
  statement: The statement to be used for the assertion.
1828
1863
  incident_behavior: The incident behavior to be applied to the assertion. Valid values are:
1829
1864
  - "raise_on_fail" or AssertionIncidentBehavior.RAISE_ON_FAIL
@@ -1850,6 +1885,12 @@ class AssertionsClient:
1850
1885
  f"Created by is not set, using {DEFAULT_CREATED_BY} as a placeholder"
1851
1886
  )
1852
1887
  created_by = DEFAULT_CREATED_BY
1888
+ criteria = SqlAssertionCriteria(
1889
+ type=criteria_type,
1890
+ change_type=criteria_change_type,
1891
+ operator=criteria_operator,
1892
+ parameters=criteria_parameters,
1893
+ )
1853
1894
  assertion_input = _SqlAssertionInput(
1854
1895
  urn=None,
1855
1896
  entity_client=self.client.entities,
@@ -2959,7 +3000,12 @@ class AssertionsClient:
2959
3000
  tags: Optional[TagsInputType] = None,
2960
3001
  updated_by: Optional[Union[str, CorpUserUrn]] = None,
2961
3002
  schedule: Optional[Union[str, models.CronScheduleClass]] = None,
2962
- definition: Optional[VolumeAssertionDefinitionInputTypes] = None,
3003
+ criteria_type: Optional[Union[str, VolumeAssertionDefinitionType]] = None,
3004
+ criteria_change_type: Optional[
3005
+ Union[str, VolumeAssertionDefinitionChangeKind]
3006
+ ] = None,
3007
+ criteria_operator: Optional[Union[str, VolumeAssertionOperator]] = None,
3008
+ criteria_parameters: Optional[VolumeAssertionDefinitionParameters] = None,
2963
3009
  ) -> VolumeAssertion:
2964
3010
  """Upsert and merge a volume assertion.
2965
3011
 
@@ -3010,25 +3056,28 @@ class AssertionsClient:
3010
3056
  The format is a cron expression, e.g. "0 * * * *" for every hour using UTC timezone.
3011
3057
  Alternatively, a models.CronScheduleClass object can be provided with string parameters
3012
3058
  cron and timezone. Use `from datahub.metadata import schema_classes as models` to import the class.
3013
- definition: The volume assertion definition. Can be provided as:
3014
- - A typed volume assertion object (RowCountTotal or RowCountChange)
3015
- - A dictionary with keys: type, operator, parameters (and kind for row_count_change)
3016
- - None to preserve the existing definition from the backend (for update operations)
3017
-
3018
- Example dictionary for row count total:
3019
- {
3020
- "type": "row_count_total",
3021
- "operator": "GREATER_THAN_OR_EQUAL_TO",
3022
- "parameters": 100
3023
- }
3024
-
3025
- Example dictionary for row count change:
3026
- {
3027
- "type": "row_count_change",
3028
- "kind": "absolute",
3029
- "operator": "LESS_THAN_OR_EQUAL_TO",
3030
- "parameters": 50
3031
- }
3059
+ criteria_type: Optional type of volume assertion. Must be either VolumeAssertionDefinitionType.ROW_COUNT_TOTAL or VolumeAssertionDefinitionType.ROW_COUNT_CHANGE.
3060
+ Raw string values are also accepted: "ROW_COUNT_TOTAL" or "ROW_COUNT_CHANGE".
3061
+ If not provided, the existing definition from the backend will be preserved (for update operations).
3062
+ Required when creating a new assertion (when urn is None).
3063
+ criteria_change_type: Optional change type for row count change assertions. Must be either VolumeAssertionDefinitionChangeKind.ABSOLUTE
3064
+ or VolumeAssertionDefinitionChangeKind.PERCENT. Required when criteria_type is VolumeAssertionDefinitionType.ROW_COUNT_CHANGE. Ignored when criteria_type
3065
+ is VolumeAssertionDefinitionType.ROW_COUNT_TOTAL. If not provided, existing value is preserved for updates.
3066
+ Raw string values are also accepted: "ABSOLUTE" or "PERCENTAGE".
3067
+ criteria_operator: Optional comparison operator for the assertion. Must be a VolumeAssertionOperator value:
3068
+ - VolumeAssertionOperator.GREATER_THAN_OR_EQUAL_TO
3069
+ - VolumeAssertionOperator.LESS_THAN_OR_EQUAL_TO
3070
+ - VolumeAssertionOperator.BETWEEN
3071
+ Raw string values are also accepted: "GREATER_THAN_OR_EQUAL_TO", "LESS_THAN_OR_EQUAL_TO", "BETWEEN".
3072
+ If not provided, existing value is preserved for updates. Required when creating a new assertion.
3073
+ criteria_parameters: Optional parameters for the assertion. For single-value operators
3074
+ (GREATER_THAN_OR_EQUAL_TO, LESS_THAN_OR_EQUAL_TO), provide a single number.
3075
+ For BETWEEN operator, provide a tuple of two numbers (min_value, max_value).
3076
+ If not provided, existing value is preserved for updates. Required when creating a new assertion.
3077
+
3078
+ Examples:
3079
+ - For single value: 100 or 50.5
3080
+ - For BETWEEN: (10, 100) or (5.0, 15.5)
3032
3081
 
3033
3082
  Returns:
3034
3083
  VolumeAssertion: The created or updated assertion.
@@ -3042,9 +3091,46 @@ class AssertionsClient:
3042
3091
  )
3043
3092
  updated_by = DEFAULT_CREATED_BY
3044
3093
 
3045
- # 1. If urn is not set, create a new assertion
3094
+ # 1. Validate criteria parameters if any are provided
3095
+ if (
3096
+ criteria_type is not None
3097
+ or criteria_operator is not None
3098
+ or criteria_parameters is not None
3099
+ ) and (
3100
+ criteria_type is None
3101
+ or criteria_operator is None
3102
+ or criteria_parameters is None
3103
+ or (
3104
+ criteria_type == VolumeAssertionDefinitionType.ROW_COUNT_CHANGE
3105
+ and criteria_change_type is None
3106
+ )
3107
+ ):
3108
+ raise SDKUsageError(
3109
+ "When providing volume assertion criteria, all required parameters must be provided "
3110
+ "(criteria_type, criteria_operator, criteria_parameters must be provided, "
3111
+ "and criteria_change_type is required when criteria_type is 'row_count_change')"
3112
+ )
3113
+
3114
+ # Assert the invariant: if criteria_type is provided, all required parameters are provided
3115
+ assert criteria_type is None or (
3116
+ criteria_operator is not None
3117
+ and criteria_parameters is not None
3118
+ and (
3119
+ criteria_type != VolumeAssertionDefinitionType.ROW_COUNT_CHANGE
3120
+ or criteria_change_type is not None
3121
+ )
3122
+ ), "criteria fields already validated"
3123
+
3124
+ # 2. If urn is not set, create a new assertion
3046
3125
  if urn is None:
3126
+ if criteria_type is None:
3127
+ raise SDKUsageError(
3128
+ "Volume assertion criteria are required when creating a new assertion"
3129
+ )
3047
3130
  logger.info("URN is not set, creating a new assertion")
3131
+ # Type narrowing: we know these are not None because of validation above
3132
+ assert criteria_operator is not None
3133
+ assert criteria_parameters is not None
3048
3134
  return self._create_volume_assertion(
3049
3135
  dataset_urn=dataset_urn,
3050
3136
  display_name=display_name,
@@ -3054,25 +3140,40 @@ class AssertionsClient:
3054
3140
  tags=tags,
3055
3141
  created_by=updated_by,
3056
3142
  schedule=schedule,
3057
- definition=definition,
3143
+ criteria_type=criteria_type,
3144
+ criteria_change_type=criteria_change_type,
3145
+ criteria_operator=criteria_operator,
3146
+ criteria_parameters=criteria_parameters,
3058
3147
  )
3059
3148
 
3060
3149
  # 2. If urn is set, prepare definition for validation
3061
- # We use temporary default definition if None is provided, just to pass the _VolumeAssertionInput validation.
3150
+ # If criteria parameters are provided, create definition from them
3151
+ # Otherwise, we use temporary default definition if None is provided, just to pass the _VolumeAssertionInput validation.
3062
3152
  # However, we keep memory of this in use_backend_definition flag, so we can later
3063
3153
  # fail if there is no definition in backend (basically, there is no assertion). That would mean that
3064
3154
  # this is a creation case and the user missed the definition parameter, which is required.
3065
3155
  # Likely this pattern never happened before because there is no a publicly documented default definition
3066
3156
  # that we can use as fallback.
3067
- use_backend_definition = definition is None
3068
- temp_definition = (
3069
- definition
3070
- if definition is not None
3071
- else RowCountTotal(
3072
- operator=VolumeAssertionOperator.GREATER_THAN_OR_EQUAL_TO,
3073
- parameters=0, # Temporary placeholder
3074
- )
3075
- )
3157
+ if criteria_type is not None:
3158
+ # Create definition from individual criteria parameters
3159
+ temp_definition: dict[str, Any] = {
3160
+ "type": criteria_type,
3161
+ "operator": criteria_operator,
3162
+ "parameters": criteria_parameters,
3163
+ }
3164
+
3165
+ if criteria_type == VolumeAssertionDefinitionType.ROW_COUNT_CHANGE:
3166
+ temp_definition["kind"] = criteria_change_type
3167
+
3168
+ use_backend_definition = False
3169
+ else:
3170
+ # No criteria provided, use backend definition
3171
+ use_backend_definition = True
3172
+ temp_definition = {
3173
+ "type": VolumeAssertionDefinitionType.ROW_COUNT_TOTAL,
3174
+ "operator": VolumeAssertionOperator.GREATER_THAN_OR_EQUAL_TO,
3175
+ "parameters": 0, # Temporary placeholder
3176
+ }
3076
3177
 
3077
3178
  # 3. Create assertion input with effective definition
3078
3179
  assertion_input = _VolumeAssertionInput(
@@ -3100,7 +3201,7 @@ class AssertionsClient:
3100
3201
  display_name=display_name,
3101
3202
  enabled=enabled,
3102
3203
  detection_mechanism=detection_mechanism,
3103
- definition=definition,
3204
+ definition=temp_definition,
3104
3205
  use_backend_definition=use_backend_definition,
3105
3206
  incident_behavior=incident_behavior,
3106
3207
  tags=tags,
@@ -3141,7 +3242,12 @@ class AssertionsClient:
3141
3242
  display_name: Optional[str] = None,
3142
3243
  enabled: Optional[bool] = None,
3143
3244
  statement: str,
3144
- criteria: SqlAssertionCriteria,
3245
+ criteria_type: Union[SqlAssertionType, str],
3246
+ criteria_change_type: Optional[Union[SqlAssertionChangeType, str]] = None,
3247
+ criteria_operator: Union[SqlAssertionOperator, str],
3248
+ criteria_parameters: Union[
3249
+ Union[float, int], tuple[Union[float, int], Union[float, int]]
3250
+ ],
3145
3251
  incident_behavior: Optional[
3146
3252
  Union[AssertionIncidentBehavior, list[AssertionIncidentBehavior]]
3147
3253
  ] = None,
@@ -3171,25 +3277,23 @@ class AssertionsClient:
3171
3277
  will be generated.
3172
3278
  enabled: Whether the assertion is enabled. If not provided, the existing value
3173
3279
  will be preserved.
3174
- criteria: The criteria to be used for the assertion. This is of type SqlAssertionCriteria. It has the following fields:
3175
- - type: The type of sql assertion. Valid values are:
3176
- - "METRIC" -> Looks at the current value of the metric.
3177
- - "METRIC_CHANGE" -> Looks at the change in the metric between the current and previous run.
3178
- - change_type: The change type of the assertion, if the type is "METRIC_CHANGE". Valid values are:
3179
- - "ABSOLUTE" -> Looks at the absolute change in the metric.
3180
- - "PERCENTAGE" -> Looks at the percentage change in the metric.
3181
- - operator: The operator to be used for the assertion. Valid values are:
3182
- - "GREATER_THAN" -> The metric value is greater than the threshold.
3183
- - "LESS_THAN" -> The metric value is less than the threshold.
3184
- - "GREATER_THAN_OR_EQUAL_TO" -> The metric value is greater than or equal to the threshold.
3185
- - "LESS_THAN_OR_EQUAL_TO" -> The metric value is less than or equal to the threshold.
3186
- - "EQUAL_TO" -> The metric value is equal to the threshold.
3187
- - "NOT_EQUAL_TO" -> The metric value is not equal to the threshold.
3188
- - "BETWEEN" -> The metric value is between the two thresholds.
3189
- - parameters: The parameters to be used for the assertion. This is of type SqlAssertionParameters. It has the following fields:
3190
- - value: The value of the metric. This can be a single value or a tuple range.
3191
- - If the operator is "BETWEEN", the value is a tuple of two values, with format min, max.
3192
- - If the operator is not "BETWEEN", the value is a single value.
3280
+ criteria_type: The type of sql assertion. Valid values are:
3281
+ - "METRIC" -> Looks at the current value of the metric.
3282
+ - "METRIC_CHANGE" -> Looks at the change in the metric between the current and previous run.
3283
+ criteria_change_type: The change type of the assertion, if the type is "METRIC_CHANGE". Valid values are:
3284
+ - "ABSOLUTE" -> Looks at the absolute change in the metric.
3285
+ - "PERCENTAGE" -> Looks at the percentage change in the metric.
3286
+ criteria_operator: The operator to be used for the assertion. Valid values are:
3287
+ - "GREATER_THAN" -> The metric value is greater than the threshold.
3288
+ - "LESS_THAN" -> The metric value is less than the threshold.
3289
+ - "GREATER_THAN_OR_EQUAL_TO" -> The metric value is greater than or equal to the threshold.
3290
+ - "LESS_THAN_OR_EQUAL_TO" -> The metric value is less than or equal to the threshold.
3291
+ - "EQUAL_TO" -> The metric value is equal to the threshold.
3292
+ - "NOT_EQUAL_TO" -> The metric value is not equal to the threshold.
3293
+ - "BETWEEN" -> The metric value is between the two thresholds.
3294
+ criteria_parameters: The parameters to be used for the assertion. This can be a single value or a tuple range.
3295
+ - If the operator is "BETWEEN", the value is a tuple of two values, with format min, max.
3296
+ - If the operator is not "BETWEEN", the value is a single value.
3193
3297
  statement: The SQL statement to be used for the assertion.
3194
3298
  - "SELECT COUNT(*) FROM table WHERE column > 100"
3195
3299
  incident_behavior: The incident behavior to be applied to the assertion. Valid values are:
@@ -3228,7 +3332,10 @@ class AssertionsClient:
3228
3332
  dataset_urn=dataset_urn,
3229
3333
  display_name=display_name,
3230
3334
  enabled=enabled if enabled is not None else True,
3231
- criteria=criteria,
3335
+ criteria_type=criteria_type,
3336
+ criteria_change_type=criteria_change_type,
3337
+ criteria_operator=criteria_operator,
3338
+ criteria_parameters=criteria_parameters,
3232
3339
  statement=statement,
3233
3340
  incident_behavior=incident_behavior,
3234
3341
  tags=tags,
@@ -3237,6 +3344,12 @@ class AssertionsClient:
3237
3344
  )
3238
3345
 
3239
3346
  # 2. If urn is set, first validate the input:
3347
+ criteria = SqlAssertionCriteria(
3348
+ type=criteria_type,
3349
+ change_type=criteria_change_type,
3350
+ operator=criteria_operator,
3351
+ parameters=criteria_parameters,
3352
+ )
3240
3353
  assertion_input = _SqlAssertionInput(
3241
3354
  urn=urn,
3242
3355
  entity_client=self.client.entities,
@@ -16,7 +16,7 @@ from datahub.sdk.main_client import DataHubClient
16
16
 
17
17
  logger = logging.getLogger(__name__)
18
18
 
19
- SubscriberInputType: TypeAlias = Union[CorpUserUrn, CorpGroupUrn]
19
+ SubscriberInputType: TypeAlias = Union[CorpUserUrn, CorpGroupUrn, str]
20
20
 
21
21
 
22
22
  ASSERTION_RELATED_ENTITY_CHANGE_TYPES = {
@@ -73,6 +73,7 @@ class SubscriptionClient:
73
73
  For datasets: subscription applies to all assertions on the dataset.
74
74
  For assertions: subscription applies only to that specific assertion.
75
75
  subscriber_urn: The URN of the user or group that will receive notifications.
76
+ Can be a string (valid corpuser or corpGroup URN) or URN object.
76
77
  entity_change_types: Specific change types to subscribe to. If None, defaults are:
77
78
  - Dataset: all existing change types
78
79
  - Assertion: assertion-related types (ASSERTION_PASSED,
@@ -91,6 +92,9 @@ class SubscriptionClient:
91
92
  # Parse URN string if needed
92
93
  parsed_urn = self._maybe_parse_urn(urn)
93
94
 
95
+ # Parse subscriber URN string if needed
96
+ parsed_subscriber_urn = self._maybe_parse_subscriber_urn(subscriber_urn)
97
+
94
98
  dataset_urn: DatasetUrn
95
99
  assertion_urn: Optional[AssertionUrn]
96
100
  dataset_urn, assertion_urn = (
@@ -100,7 +104,7 @@ class SubscriptionClient:
100
104
  )
101
105
 
102
106
  logger.info(
103
- f"Subscribing to dataset={dataset_urn} assertion={assertion_urn} for subscriber={subscriber_urn} with change types: {entity_change_types}"
107
+ f"Subscribing to dataset={dataset_urn} assertion={assertion_urn} for subscriber={parsed_subscriber_urn} with change types: {entity_change_types}"
104
108
  )
105
109
 
106
110
  # Get entity change types (use all if none provided)
@@ -111,16 +115,16 @@ class SubscriptionClient:
111
115
 
112
116
  existing_subscriptions = self.client.resolve.subscription( # type: ignore[attr-defined]
113
117
  entity_urn=dataset_urn.urn(),
114
- actor_urn=subscriber_urn.urn(),
118
+ actor_urn=parsed_subscriber_urn.urn(),
115
119
  )
116
120
  if not existing_subscriptions:
117
121
  # new subscription
118
122
  subscription = Subscription(
119
123
  info=models.SubscriptionInfoClass(
120
124
  entityUrn=dataset_urn.urn(),
121
- actorUrn=subscriber_urn.urn(),
125
+ actorUrn=parsed_subscriber_urn.urn(),
122
126
  actorType=CorpUserUrn.ENTITY_TYPE
123
- if isinstance(subscriber_urn, CorpUserUrn)
127
+ if isinstance(parsed_subscriber_urn, CorpUserUrn)
124
128
  else CorpGroupUrn.ENTITY_TYPE,
125
129
  types=[
126
130
  models.SubscriptionTypeClass.ENTITY_CHANGE,
@@ -158,7 +162,7 @@ class SubscriptionClient:
158
162
  return
159
163
  else:
160
164
  raise SdkUsageError(
161
- f"We have a mesh here - {len(existing_subscriptions)} subscriptions found for dataset={dataset_urn} assertion={assertion_urn} and subscriber={subscriber_urn}!"
165
+ f"We have a mesh here - {len(existing_subscriptions)} subscriptions found for dataset={dataset_urn} assertion={assertion_urn} and subscriber={parsed_subscriber_urn}!"
162
166
  )
163
167
 
164
168
  def list_subscriptions(
@@ -178,7 +182,8 @@ class SubscriptionClient:
178
182
  entity_change_types: Optional filter to return only subscriptions for specific
179
183
  change types. If None, returns subscriptions for all change types.
180
184
  subscriber_urn: Optional filter to return only subscriptions for a specific user
181
- or group. If None, returns subscriptions for all subscribers.
185
+ or group. Can be a string (valid corpuser or corpGroup URN) or URN object.
186
+ If None, returns subscriptions for all subscribers.
182
187
 
183
188
  Returns:
184
189
  List[Subscription]: List of matching subscription objects.
@@ -227,6 +232,7 @@ class SubscriptionClient:
227
232
  Args:
228
233
  urn: URN (string or URN object) of the dataset or assertion to unsubscribe from.
229
234
  subscriber_urn: User or group URN to unsubscribe.
235
+ Can be a string (valid corpuser or corpGroup URN) or URN object.
230
236
  entity_change_types: Specific change types to remove. If None, defaults are:
231
237
  - Dataset: all existing change types in the subscription
232
238
  - Assertion: assertion-related types (ASSERTION_PASSED,
@@ -248,6 +254,9 @@ class SubscriptionClient:
248
254
  # Parse URN string if needed
249
255
  parsed_urn = self._maybe_parse_urn(urn)
250
256
 
257
+ # Parse subscriber URN string if needed
258
+ parsed_subscriber_urn = self._maybe_parse_subscriber_urn(subscriber_urn)
259
+
251
260
  dataset_urn: DatasetUrn
252
261
  assertion_urn: Optional[AssertionUrn]
253
262
  dataset_urn, assertion_urn = (
@@ -257,23 +266,23 @@ class SubscriptionClient:
257
266
  )
258
267
 
259
268
  logger.info(
260
- f"Unsubscribing from dataset={dataset_urn}{f' assertion={assertion_urn}' if assertion_urn else ''} for subscriber={subscriber_urn} with change types: {entity_change_types}"
269
+ f"Unsubscribing from dataset={dataset_urn}{f' assertion={assertion_urn}' if assertion_urn else ''} for subscriber={parsed_subscriber_urn} with change types: {entity_change_types}"
261
270
  )
262
271
 
263
272
  # Find existing subscription
264
273
  existing_subscription_urns = self.client.resolve.subscription( # type: ignore[attr-defined]
265
274
  entity_urn=dataset_urn.urn(),
266
- actor_urn=subscriber_urn.urn(),
275
+ actor_urn=parsed_subscriber_urn.urn(),
267
276
  )
268
277
 
269
278
  if not existing_subscription_urns:
270
279
  logger.info(
271
- f"No subscription found for dataset={dataset_urn} and subscriber={subscriber_urn}"
280
+ f"No subscription found for dataset={dataset_urn} and subscriber={parsed_subscriber_urn}"
272
281
  )
273
282
  return
274
283
  elif len(existing_subscription_urns) > 1:
275
284
  raise SdkUsageError(
276
- f"Multiple subscriptions found for dataset={dataset_urn} and subscriber={subscriber_urn}. "
285
+ f"Multiple subscriptions found for dataset={dataset_urn} and subscriber={parsed_subscriber_urn}. "
277
286
  f"Expected at most 1, got {len(existing_subscription_urns)}"
278
287
  )
279
288
 
@@ -659,6 +668,33 @@ class SubscriptionClient:
659
668
  f"Unsupported URN type. Only dataset and assertion URNs are supported, got: {urn}"
660
669
  )
661
670
 
671
+ def _maybe_parse_subscriber_urn(
672
+ self, subscriber_urn: SubscriberInputType
673
+ ) -> Union[CorpUserUrn, CorpGroupUrn]:
674
+ """Parse subscriber URN string into appropriate URN object if needed.
675
+
676
+ Args:
677
+ subscriber_urn: String URN or URN object (CorpUserUrn or CorpGroupUrn)
678
+
679
+ Returns:
680
+ Parsed URN object (CorpUserUrn or CorpGroupUrn)
681
+
682
+ Raises:
683
+ SdkUsageError: If the URN string format is invalid or unsupported
684
+ """
685
+ if isinstance(subscriber_urn, (CorpUserUrn, CorpGroupUrn)):
686
+ return subscriber_urn
687
+
688
+ # Try to determine URN type from string format
689
+ if ":corpuser:" in subscriber_urn:
690
+ return CorpUserUrn.from_string(subscriber_urn)
691
+ elif ":corpGroup:" in subscriber_urn:
692
+ return CorpGroupUrn.from_string(subscriber_urn)
693
+ else:
694
+ raise SdkUsageError(
695
+ f"Unsupported subscriber URN type. Only corpuser and corpGroup URNs are supported, got: {subscriber_urn}"
696
+ )
697
+
662
698
  def _fetch_dataset_from_assertion(
663
699
  self, assertion_urn: AssertionUrn
664
700
  ) -> Tuple[DatasetUrn, AssertionUrn]: