-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathevent.py
More file actions
123 lines (102 loc) · 3.63 KB
/
Copy pathevent.py
File metadata and controls
123 lines (102 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# ruff: noqa: N815
from dataclasses import dataclass, field
from typing import Dict, Optional, Any, List
from datetime import datetime, timezone
from .user import DevCycleUser
class EventType:
VariableEvaluated = "variableEvaluated"
AggVariableEvaluated = "aggVariableEvaluated"
VariableDefaulted = "variableDefaulted"
AggVariableDefaulted = "aggVariableDefaulted"
CustomEvent = "customEvent"
@dataclass(order=False)
class DevCycleEvent:
type: Optional[str] = None
target: Optional[str] = None
date: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
value: Optional[int] = None
metaData: Optional[Dict[str, str]] = None
def to_json(self, use_bucketing_api_format: bool = False) -> Dict[str, Any]:
json_dict = {
key: getattr(self, key)
for key in self.__dataclass_fields__
if getattr(self, key) is not None and key != "date"
}
if self.date:
if use_bucketing_api_format:
# convert to timestamp in milliseconds as required by the bucketing API
json_dict["date"] = int(self.date.timestamp() * 1000)
else:
# convert to UTC and format as ISO string
json_dict["date"] = self.date.astimezone(tz=timezone.utc).isoformat()
return json_dict
@dataclass(order=False)
class RequestEvent:
"""
An event generated by local bucketing event that can be sent to the Events API
Not interfaced by developers, purely for internal use
"""
type: str
user_id: str
# will be a timestamp in iso format
clientDate: str
# will be a timestamp in iso format
date: str
target: Optional[str] = None
customType: Optional[str] = None
value: Optional[float] = 0
featureVars: Dict[str, str] = field(default_factory=dict)
metaData: Optional[Dict[str, str]] = None
def to_json(self):
json_obj = {}
for key in self.__dataclass_fields__:
json_obj[key] = getattr(self, key)
return json_obj
@classmethod
def from_json(cls, data: dict) -> "RequestEvent":
return cls(
type=data["type"],
user_id=data["user_id"],
clientDate=data["clientDate"],
date=data["date"],
target=data.get("target"),
customType=data.get("customType"),
value=data.get("value", 0),
featureVars=data.get("featureVars", {}),
metaData=data.get("metaData"),
)
@dataclass()
class UserEventsBatchRecord:
"""
A collection of events generated by local bucketing library for a single user
"""
user: DevCycleUser
events: List[RequestEvent]
def to_json(self) -> Dict[str, Any]:
return {
"user": self.user.to_json(),
"events": [event.to_json() for event in self.events],
}
@classmethod
def from_json(cls, data: dict) -> "UserEventsBatchRecord":
return cls(
user=DevCycleUser.from_json(data["user"]),
events=[RequestEvent.from_json(element) for element in data["events"]],
)
@dataclass()
class FlushPayload:
"""
A collection of events exported by the local bucketing library that can be sent to the Events API as a batch
"""
payloadId: str
records: List[UserEventsBatchRecord]
eventCount: int
@classmethod
def from_json(cls, data: dict) -> "FlushPayload":
return cls(
payloadId=data["payloadId"],
eventCount=data["eventCount"],
records=[
UserEventsBatchRecord.from_json(element) for element in data["records"]
],
)