Skip to content

Commit

Permalink
api/view: improve the collect of the Schema1 events
Browse files Browse the repository at this point in the history
Harmonize how we collect we prepare the Schema1 events and how we
do the payload validation and the exception handling.
  • Loading branch information
goneri committed Jun 19, 2024
1 parent f84b4fa commit 97ba1a3
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 356 deletions.
93 changes: 93 additions & 0 deletions ansible_wisdom/ai/api/telemetry/schema1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Copyright Red Hat
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from enum import Enum

from attr import Factory, field, frozen
from attrs import define, validators, fields
from django.utils import timezone

from attr import asdict

import platform
from ansible_ai_connect.healthcheck.version_info import VersionInfo
from ansible_ai_connect.users.models import User
version_info = VersionInfo()

@define
class ResponsePayload:
exception: str = field(validator=validators.instance_of(str), converter=str, default="")

@define
class Schema1Event:
event_name: str = "noName"
imageTags: str = field(validator=validators.instance_of(str), converter=str, default=version_info.image_tags)
hostname: str = field(validator=validators.instance_of(str), converter=str, default=platform.node())
groups: list[str] = Factory(list)

rh_user_has_seat: bool = False
rh_user_org_id: int|None = None
timestamp = timezone.now().isoformat()
modelName: str = field(validator=validators.instance_of(str), converter=str, default="")
exception: bool = False
response: ResponsePayload|None = ResponsePayload()
user: User|None = None
duration: int = field(validator=validators.instance_of(int), converter=int, default=0)

def set_user(self, user):
self.user = user
self.rh_user_has_seat = user.rh_user_has_seat
self.rh_user_org_id = user.org_id
self.groups = list(user.groups.values_list("name", flat=True))

def set_exception(self, exception):
if exception:
self.exception = True
self.response.exception=str(exception)

def set_validated_data(self, validated_data):
for field, value in validated_data.items():
if hasattr(self, field):
setattr(self, field, value)


def get_event_dict(self):
# NOTE: The allowed fields should be moved in the event class itslef
def my_filter(a, v):
return not a.name in ["event_name", "user"]
return asdict(self, filter=my_filter)

@define
class ExplainPlaybookSchema1Event(Schema1Event):
event_name: str = "explainPlaybook"
explanationId: str = field(validator=validators.instance_of(str), converter=str, default="")

@define
class CodegenPlaybookSchema1Event(Schema1Event):
event_name: str = "codegenPlaybook"
generationId: str = field(validator=validators.instance_of(str), converter=str, default="")
wizardId: str = field(validator=validators.instance_of(str), converter=str, default="")
playbook_length: int|None = None
def set_validated_data(self, validated_data):
super().set_validated_data(validated_data)
self.playbook_length = len(validated_data.get("playbook", ""))

@define
class ContentMatchSchema1Event(Schema1Event):
event_name: str = "codematch"
request_data: dict|None = None
metadata: list|None = None # TODO
def set_validated_data(self, validated_data):
super().set_validated_data(validated_data)
self.request_data = validated_data
2 changes: 2 additions & 0 deletions ansible_wisdom/ai/api/utils/analytics_telemetry_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# Schema2

from enum import Enum

from attr import Factory, field, frozen
Expand Down
10 changes: 10 additions & 0 deletions ansible_wisdom/ai/api/utils/segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ def base_send_segment_event(
send_segment_event(event, "segmentError", user)


def send_schema1_event(event_obj) -> None:
print(event_obj)
if not settings.SEGMENT_WRITE_KEY:
logger.info("segment write key not set, skipping event")
return
base_send_segment_event(
event_obj.get_event_dict(), event_obj.event_name, event_obj.user, analytics
)


def redact_seated_users_data(event: Dict[str, Any], allow_list: Dict[str, Any]) -> Dict[str, Any]:
"""
Copy a dictionary to another dictionary using a nested list of allowed keys.
Expand Down
Loading

0 comments on commit 97ba1a3

Please sign in to comment.