@@ -8831,7 +8831,7 @@ def assert_passing(self) -> None:
8831
8831
raise AssertionError(msg)
8832
8832
8833
8833
def assert_below_threshold(
8834
- self, level: str = "warning", i: int = None, message: str = None
8834
+ self, level: str = "warning", i: int | None = None, message: str | None = None
8835
8835
) -> None:
8836
8836
"""
8837
8837
Raise an `AssertionError` if validation steps exceed a specified threshold level.
@@ -8940,12 +8940,12 @@ def assert_below_threshold(
8940
8940
8941
8941
See Also
8942
8942
--------
8943
- - [`warning()`](`pointblank.Validate.warning`): Get the 'warning' status for each validation
8943
+ - [`warning()`](`pointblank.Validate.warning`): get the 'warning' status for each validation
8944
8944
step
8945
- - [`error()`](`pointblank.Validate.error`): Get the 'error' status for each validation step
8946
- - [`critical()`](`pointblank.Validate.critical`): Get the 'critical' status for each
8945
+ - [`error()`](`pointblank.Validate.error`): get the 'error' status for each validation step
8946
+ - [`critical()`](`pointblank.Validate.critical`): get the 'critical' status for each
8947
8947
validation step
8948
- - [`assert_passing()`](`pointblank.Validate.assert_passing`): Assert all validations pass
8948
+ - [`assert_passing()`](`pointblank.Validate.assert_passing`): assert all validations pass
8949
8949
completely
8950
8950
"""
8951
8951
# Check if validation has been interrogated
@@ -8991,6 +8991,145 @@ def assert_below_threshold(
8991
8991
)
8992
8992
raise AssertionError(msg)
8993
8993
8994
+ def above_threshold(self, level: str = "warning", i: int | None = None) -> bool:
8995
+ """
8996
+ Check if any validation steps exceed a specified threshold level.
8997
+
8998
+ The `above_threshold()` method checks whether validation steps exceed a given threshold
8999
+ level. This provides a non-exception-based alternative to
9000
+ [`assert_below_threshold()`](`pointblank.Validate.assert_below_threshold`) for conditional
9001
+ workflow control based on validation results.
9002
+
9003
+ This method is useful in scenarios where you want to check if any validation steps failed
9004
+ beyond a certain threshold without raising an exception, allowing for more flexible
9005
+ programmatic responses to validation issues.
9006
+
9007
+ Parameters
9008
+ ----------
9009
+ level
9010
+ The threshold level to check against. Valid options are: `"warning"` (the least severe
9011
+ threshold level), `"error"` (the middle severity threshold level), and `"critical"` (the
9012
+ most severe threshold level). The default is `"warning"`.
9013
+ i
9014
+ Specific validation step number(s) to check. If a single integer, checks only that step.
9015
+ If a list of integers, checks all specified steps. If `None` (the default), checks all
9016
+ validation steps. Step numbers are 1-based (first step is `1`, not `0`).
9017
+
9018
+ Returns
9019
+ -------
9020
+ bool
9021
+ `True` if any of the specified validation steps exceed the given threshold level,
9022
+ `False` otherwise.
9023
+
9024
+ Raises
9025
+ ------
9026
+ ValueError
9027
+ If an invalid threshold level is provided.
9028
+
9029
+ Examples
9030
+ --------
9031
+ ```{python}
9032
+ #| echo: false
9033
+ #| output: false
9034
+ import pointblank as pb
9035
+ pb.config(report_incl_header=False, report_incl_footer=False, preview_incl_header=False)
9036
+ ```
9037
+ Below are some examples of how to use the `above_threshold()` method. First, we'll create a
9038
+ simple Polars DataFrame with a single column (`values`).
9039
+
9040
+ ```{python}
9041
+ import polars as pl
9042
+
9043
+ tbl = pl.DataFrame({
9044
+ "values": [1, 2, 3, 4, 5, 0, -1]
9045
+ })
9046
+ ```
9047
+
9048
+ Then a validation plan will be created with thresholds (`warning=0.1`, `error=0.2`,
9049
+ `critical=0.3`). After interrogating, we display the validation report table:
9050
+
9051
+ ```{python}
9052
+ import pointblank as pb
9053
+
9054
+ validation = (
9055
+ pb.Validate(data=tbl, thresholds=(0.1, 0.2, 0.3))
9056
+ .col_vals_gt(columns="values", value=0)
9057
+ .col_vals_lt(columns="values", value=10)
9058
+ .col_vals_between(columns="values", left=0, right=5)
9059
+ .interrogate()
9060
+ )
9061
+
9062
+ validation
9063
+ ```
9064
+
9065
+ Let's check if any steps exceed the 'warning' threshold with the `above_threshold()` method.
9066
+ A message will be printed if that's the case:
9067
+
9068
+ ```{python}
9069
+ if validation.above_threshold(level="warning"):
9070
+ print("Some steps have exceeded the warning threshold")
9071
+ ```
9072
+
9073
+ Check if only steps 2 and 3 exceed the 'error' threshold through use of the `i=` argument:
9074
+
9075
+ ```{python}
9076
+ if validation.above_threshold(level="error", i=[2, 3]):
9077
+ print("Steps 2 and/or 3 have exceeded the error threshold")
9078
+ ```
9079
+
9080
+ You can use this in a workflow to conditionally trigger processes. Here's a snippet of how
9081
+ you might use this in a function:
9082
+
9083
+ ```python
9084
+ def process_data(validation_obj):
9085
+ # Only continue processing if validation passes critical thresholds
9086
+ if not validation_obj.above_threshold(level="critical"):
9087
+ # Continue with processing
9088
+ print("Data meets critical quality thresholds, proceeding...")
9089
+ return True
9090
+ else:
9091
+ # Log failure and stop processing
9092
+ print("Data fails critical quality checks, aborting...")
9093
+ return False
9094
+ ```
9095
+
9096
+ Note that this is just a suggestion for how to implement conditional workflow processes. You
9097
+ should adapt this pattern to your specific requirements, which might include different
9098
+ threshold levels, custom logging mechanisms, or integration with your organization's data
9099
+ pipelines and notification systems.
9100
+
9101
+ See Also
9102
+ --------
9103
+ - [`assert_below_threshold()`](`pointblank.Validate.assert_below_threshold`): a similar
9104
+ method that raises an exception if thresholds are exceeded
9105
+ - [`warning()`](`pointblank.Validate.warning`): get the 'warning' status for each validation
9106
+ step
9107
+ - [`error()`](`pointblank.Validate.error`): get the 'error' status for each validation step
9108
+ - [`critical()`](`pointblank.Validate.critical`): get the 'critical' status for each
9109
+ validation step
9110
+ """
9111
+ # Ensure validation has been run
9112
+ if not hasattr(self, "time_start") or self.time_start is None:
9113
+ return False
9114
+
9115
+ # Validate the level parameter
9116
+ level = level.lower()
9117
+ if level not in ["warning", "error", "critical"]:
9118
+ raise ValueError(
9119
+ f"Invalid threshold level: {level}. Must be one of 'warning', 'error', or 'critical'."
9120
+ )
9121
+
9122
+ # Get the threshold status using the appropriate method
9123
+ if level == "warning":
9124
+ status = self.warning(i=i)
9125
+ elif level == "error":
9126
+ status = self.error(i=i)
9127
+ elif level == "critical":
9128
+ status = self.critical(i=i)
9129
+
9130
+ # Return True if any steps exceeded the threshold
9131
+ return any(status.values())
9132
+
8994
9133
def n(self, i: int | list[int] | None = None, scalar: bool = False) -> dict[int, int] | int:
8995
9134
"""
8996
9135
Provides a dictionary of the number of test units for each validation step.
0 commit comments