Skip to content

Commit

Permalink
Add support for composite analyzer config (#49)
Browse files Browse the repository at this point in the history
* Add support for composite analyzer config
* Update schema.json with composite analyzers
  • Loading branch information
vsuen authored Oct 16, 2023
1 parent a86a49b commit c9d6c2d
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 2 deletions.
10 changes: 9 additions & 1 deletion whylabs_toolkit/monitor/manager/monitor_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def __init__(self, monitor_id: str, dataset_id: Optional[str] = None, config: Co
SeasonalConfig,
FrequentStringComparisonConfig,
ListComparisonConfig,
ConjunctionConfig,
DisjunctionConfig,
]
] = None
self._target_columns: Optional[List[str]] = []
Expand Down Expand Up @@ -124,6 +126,8 @@ def config(
SeasonalConfig,
FrequentStringComparisonConfig,
ListComparisonConfig,
ConjunctionConfig,
DisjunctionConfig,
]
]:
return self._analyzer_config
Expand All @@ -139,6 +143,8 @@ def config(
SeasonalConfig,
FrequentStringComparisonConfig,
ListComparisonConfig,
ConjunctionConfig,
DisjunctionConfig,
],
) -> None:
self._analyzer_config = config
Expand Down Expand Up @@ -169,7 +175,7 @@ def is_constraint(self, is_constraint: bool) -> None:
raise ValueError("Config must first be set")
tags = set(self._analyzer_tags or [])
if is_constraint:
if not isinstance(self._analyzer_config, (FixedThresholdsConfig)):
if not isinstance(self._analyzer_config, (FixedThresholdsConfig, ConjunctionConfig, DisjunctionConfig)):
raise ValueError("Constraint can only be set with FixedThresholdsConfig")
tags.add(TAG_ANALYZER_CONSTRAINT)
else:
Expand Down Expand Up @@ -295,6 +301,8 @@ def __configure_target_matrix(self) -> None:

def __set_dataset_matrix_for_dataset_metric(self) -> None:
if self._analyzer_config:
if isinstance(self._analyzer_config, (ConjunctionConfig, DisjunctionConfig)):
return None
if isinstance(self._analyzer_config.metric, DatasetMetric) and isinstance(
self._target_matrix, ColumnMatrix
):
Expand Down
2 changes: 2 additions & 0 deletions whylabs_toolkit/monitor/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
"ColumnListChangeConfig",
"SeasonalConfig",
"StddevConfig",
"ConjunctionConfig",
"DisjunctionConfig",
# targets
"DatasetMatrix",
"ColumnMatrix",
Expand Down
2 changes: 2 additions & 0 deletions whylabs_toolkit/monitor/models/analyzer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"ListComparisonConfig",
"FrequentStringComparisonConfig",
"StddevConfig",
"ConjunctionConfig",
"DisjunctionConfig",
# enums
"DiffMode",
"ThresholdType",
Expand Down
20 changes: 20 additions & 0 deletions whylabs_toolkit/monitor/models/analyzer/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class AlgorithmType(str, Enum):
seasonal = "seasonal"
fixed = "fixed"
experimental = "experimental"
conjunction = "conjunction"
disjunction = "disjunction"


class DatasetMetric(str, Enum):
Expand Down Expand Up @@ -384,3 +386,21 @@ class DiffConfig(AlgorithmConfig):
"the target's metric and the baseline metric. Both of these metrics MUST be in rolled up form",
)
baseline: Union[TrailingWindowBaseline, ReferenceProfileId, TimeRangeBaseline, SingleBatchBaseline]


class ConjunctionConfig(NoExtrasBaseModel):
"""Conjunction (ANDs) composite analyzer joining multiple analyzers."""

type: Literal[AlgorithmType.conjunction] = AlgorithmType.conjunction
analyzerIds: List[str] = Field(
description="The corresponding analyzer IDs for the conjunction.",
)


class DisjunctionConfig(NoExtrasBaseModel):
"""Disjunction (ORs) composite analyzer joining multiple analyzers."""

type: Literal[AlgorithmType.disjunction] = AlgorithmType.disjunction
analyzerIds: List[str] = Field(
description="The corresponding analyzer IDs for the disjunction.",
)
4 changes: 4 additions & 0 deletions whylabs_toolkit/monitor/models/analyzer/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
FixedThresholdsConfig,
SeasonalConfig,
StddevConfig,
ConjunctionConfig,
DisjunctionConfig,
)
from .targets import ColumnMatrix, DatasetMatrix

Expand Down Expand Up @@ -111,6 +113,8 @@ class Analyzer(NoExtrasBaseModel):
DriftConfig,
ComparisonConfig,
SeasonalConfig,
ConjunctionConfig,
DisjunctionConfig,
] = Field(description="The configuration map of the analyzer", discriminator="type")

class Config:
Expand Down
70 changes: 69 additions & 1 deletion whylabs_toolkit/monitor/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,64 @@
},
"additionalProperties": false
},
"ConjunctionConfig": {
"title": "ConjunctionConfig",
"description": "Conjunction (ANDs) composite analyzer joining multiple analyzers\n ",
"type": "object",
"properties": {
"type": {
"title": "Type",
"enum": [
"conjunction"
],
"type": "string"
},
"analyzerIds": {
"title": "AnalyzerIds",
"description": "The corresponding analyzer IDs for the conjunction.",
"maxItems": 10,
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z0-9_\\-]+$"
}
}
},
"required": [
"type",
"analyzerIds"
],
"additionalProperties": false
},
"DisjunctionConfig": {
"title": "DisjunctionConfig",
"description": "Disjunction (ORs) composite analyzer joining multiple analyzers\n ",
"type": "object",
"properties": {
"type": {
"title": "Type",
"enum": [
"disjunction"
],
"type": "string"
},
"analyzerIds": {
"title": "AnalyzerIds",
"description": "The corresponding analyzer IDs for the conjunction.",
"maxItems": 10,
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z0-9_\\-]+$"
}
}
},
"required": [
"type",
"analyzerIds"
],
"additionalProperties": false
},
"DatasetMetric": {
"title": "DatasetMetric",
"description": "Metrics that are applicable at the dataset level.",
Expand Down Expand Up @@ -656,7 +714,7 @@
},
"ThresholdType": {
"title": "ThresholdType",
"description": "Threshold Type declaring the upper and lower bound.\n\nBy default an anomaly will be generated when the target is above or below the baseline\nby the specified threshold.\n\nIf its only desirable to alert when the target is above the\nbaseline and not the other way around, specify upper for your ThresholdType.",
"description": "Threshold Type declaring the upper and lower bound.\n\n By default an anomaly will be generated when the target is above or below the baseline\n by the specified threshold.\n\n If its only desirable to alert when the target is above the\n baseline and not the other way around, specify upper for your ThresholdType.\n ",
"enum": [
"lower",
"upper"
Expand Down Expand Up @@ -1576,6 +1634,8 @@
"expected",
"column_list",
"comparison",
"conjunction",
"disjunction",
"list_comparison",
"frequent_string_comparison",
"diff",
Expand Down Expand Up @@ -1902,6 +1962,8 @@
"discriminator": {
"propertyName": "type",
"mapping": {
"conjunction": "#/definitions/ConjunctionConfig",
"disjunction": "#/definitions/DisjunctionConfig",
"diff": "#/definitions/DiffConfig",
"comparison": "#/definitions/ComparisonConfig",
"list_comparison": "#/definitions/ListComparisonConfig",
Expand All @@ -1915,6 +1977,12 @@
}
},
"oneOf": [
{
"$ref": "#/definitions/ConjunctionConfig"
},
{
"$ref": "#/definitions/DisjunctionConfig"
},
{
"$ref": "#/definitions/DiffConfig"
},
Expand Down

0 comments on commit c9d6c2d

Please sign in to comment.