Skip to content

Commit

Permalink
[MAINTENANCE] Instrument analytics for Checkpoint action creation and…
Browse files Browse the repository at this point in the history
… runs (#10597)
  • Loading branch information
cdkini authored Oct 31, 2024
1 parent 76edf1f commit 8551670
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 4 deletions.
1 change: 1 addition & 0 deletions great_expectations/analytics/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
EXPECTATION_SUITE_EXPECTATION_UPDATED: Action = Action("expectation_suite.expectation_updated")
VALIDATION_DEFINITION_CREATED: Action = Action("validation_definition.created")
VALIDATION_DEFINITION_DELETED: Action = Action("validation_definition.deleted")
NOTIFICATION_ACTION_RAN: Action = Action("notification.ran")
40 changes: 38 additions & 2 deletions great_expectations/analytics/events.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from dataclasses import dataclass
from typing import ClassVar, List
from dataclasses import asdict, dataclass
from typing import ClassVar, List, Literal

from great_expectations.analytics.actions import (
CHECKPOINT_CREATED,
Expand All @@ -14,6 +14,7 @@
EXPECTATION_SUITE_EXPECTATION_CREATED,
EXPECTATION_SUITE_EXPECTATION_DELETED,
EXPECTATION_SUITE_EXPECTATION_UPDATED,
NOTIFICATION_ACTION_RAN,
VALIDATION_DEFINITION_CREATED,
VALIDATION_DEFINITION_DELETED,
)
Expand Down Expand Up @@ -155,6 +156,12 @@ def _properties(self) -> dict:
}


@dataclass
class ActionInfo:
type: str
notify_on: Literal["all", "failure", "success"] | None


@dataclass
class CheckpointCreatedEvent(_CheckpointEvent):
_allowed_actions: ClassVar[List[Action]] = [CHECKPOINT_CREATED]
Expand All @@ -163,8 +170,10 @@ def __init__(
self,
checkpoint_id: str | None = None,
validation_definition_ids: list[str | None] | None = None,
actions: list[ActionInfo] | None = None,
):
self.validation_definition_ids = validation_definition_ids
self.actions = actions or []
super().__init__(
action=CHECKPOINT_CREATED,
checkpoint_id=checkpoint_id,
Expand All @@ -174,6 +183,7 @@ def __init__(
def _properties(self) -> dict:
return {
"validation_definition_ids": self.validation_definition_ids,
"actions": [asdict(action) for action in self.actions],
**super()._properties(),
}

Expand Down Expand Up @@ -263,3 +273,29 @@ def _properties(self) -> dict:
"error_type": self.error_type,
"store_name": self.store_name,
}


@dataclass
class NotificationActionRanEvent(Event):
_allowed_actions: ClassVar[List[Action]] = [NOTIFICATION_ACTION_RAN]

def __init__(
self,
type: Literal["slack", "microsoft", "email"],
notify_type: Literal["all", "failure", "success"],
checkpoint_id: str | None,
):
self.type = type
self.notify_type = notify_type
self.checkpoint_id = checkpoint_id
super().__init__(
action=NOTIFICATION_ACTION_RAN,
)

@override
def _properties(self) -> dict:
return {
"type": self.type,
"checkpoint_id": self.checkpoint_id,
"notify_type": self.notify_type,
}
30 changes: 29 additions & 1 deletion great_expectations/checkpoint/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
from typing_extensions import Annotated

from great_expectations._docs_decorators import public_api
from great_expectations.analytics.client import submit as submit_event
from great_expectations.analytics.events import (
NotificationActionRanEvent,
)
from great_expectations.checkpoint.util import (
send_email,
send_microsoft_teams_notifications,
Expand Down Expand Up @@ -289,7 +293,16 @@ def run(
run_id=checkpoint_result.run_id,
)

return self._send_slack_notification(payload=payload)
result = self._send_slack_notification(payload=payload)

checkpoint = checkpoint_result.checkpoint_config
submit_event(
event=NotificationActionRanEvent(
type=self.type, notify_type=self.notify_on, checkpoint_id=checkpoint.id
)
)

return result

def _render_validation_result(
self,
Expand Down Expand Up @@ -473,6 +486,14 @@ def run(self, checkpoint_result: CheckpointResult, action_context: ActionContext
payload=payload,
microsoft_teams_webhook=webhook,
)

checkpoint = checkpoint_result.checkpoint_config
submit_event(
event=NotificationActionRanEvent(
type=self.type, notify_type=self.notify_on, checkpoint_id=checkpoint.id
)
)

return {"microsoft_teams_notification_result": teams_notif_result}


Expand Down Expand Up @@ -676,6 +697,13 @@ def run(
use_ssl=self.use_ssl,
)

checkpoint = checkpoint_result.checkpoint_config
submit_event(
event=NotificationActionRanEvent(
type=self.type, notify_type=self.notify_on, checkpoint_id=checkpoint.id
)
)

# sending payload back as dictionary
return {"email_result": email_result}

Expand Down
12 changes: 11 additions & 1 deletion great_expectations/core/factory/checkpoint_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from great_expectations._docs_decorators import public_api
from great_expectations.analytics.client import submit as submit_event
from great_expectations.analytics.events import (
ActionInfo,
CheckpointCreatedEvent,
CheckpointDeletedEvent,
)
Expand Down Expand Up @@ -52,7 +53,16 @@ def add(self, checkpoint: Checkpoint) -> Checkpoint:
event=CheckpointCreatedEvent(
checkpoint_id=persisted_checkpoint.id,
validation_definition_ids=[
vd.id for vd in persisted_checkpoint.validation_definitions
validation_definition.id
for validation_definition in checkpoint.validation_definitions
],
actions=[
ActionInfo(
type=action.type,
# notify_on is not a property of all Actions
notify_on=getattr(action, "notify_on", None),
)
for action in checkpoint.actions
],
)
)
Expand Down
27 changes: 27 additions & 0 deletions tests/analytics/test_events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pytest

from great_expectations.analytics.events import (
ActionInfo,
CheckpointCreatedEvent,
DataContextInitializedEvent,
ExpectationSuiteCreatedEvent,
ExpectationSuiteDeletedEvent,
Expand Down Expand Up @@ -69,6 +71,31 @@
},
id="ExpectationSuiteDeletedEvent",
),
pytest.param(
CheckpointCreatedEvent(
checkpoint_id="a7a0ec12-9a01-4c02-938c-975826df87d3",
validation_definition_ids=[
"b60bed67-268c-413d-8ad2-77b549314a51",
"b217cac6-1a6d-4b3f-bd63-3fd28c11add5",
],
actions=[
ActionInfo(type="email", notify_on="failure"),
ActionInfo(type="microsoft", notify_on="all"),
],
),
{
"checkpoint_id": "a7a0ec12-9a01-4c02-938c-975826df87d3",
"validation_definition_ids": [
"b60bed67-268c-413d-8ad2-77b549314a51",
"b217cac6-1a6d-4b3f-bd63-3fd28c11add5",
],
"actions": [
{"type": "email", "notify_on": "failure"},
{"type": "microsoft", "notify_on": "all"},
],
},
id="CheckpointCreatedEvent",
),
],
)
@pytest.mark.unit
Expand Down

0 comments on commit 8551670

Please sign in to comment.