Skip to content

Commit a6709f2

Browse files
feat(track): Introducing easier event tracking (#155)
1 parent e03b60b commit a6709f2

File tree

4 files changed

+86
-232
lines changed

4 files changed

+86
-232
lines changed

optimizely/event_builder.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2016-2018, Optimizely
1+
# Copyright 2016-2019, Optimizely
22
# Licensed under the Apache License, Version 2.0 (the "License");
33
# you may not use this file except in compliance with the License.
44
# You may obtain a copy of the License at
@@ -130,6 +130,7 @@ def _get_common_params(self, user_id, attributes):
130130
commonParams[self.EventParams.USERS][0][self.EventParams.ATTRIBUTES] = self._get_attributes(attributes)
131131

132132
commonParams[self.EventParams.SOURCE_SDK_TYPE] = 'python-sdk'
133+
commonParams[self.EventParams.ENRICH_DECISIONS] = True
133134
commonParams[self.EventParams.SOURCE_SDK_VERSION] = version.__version__
134135
commonParams[self.EventParams.ANONYMIZE_IP] = self._get_anonymize_ip()
135136
commonParams[self.EventParams.REVISION] = self._get_revision()
@@ -152,6 +153,7 @@ class EventParams(object):
152153
CAMPAIGN_ID = 'campaign_id'
153154
VARIATION_ID = 'variation_id'
154155
END_USER_ID = 'visitor_id'
156+
ENRICH_DECISIONS = 'enrich_decisions'
155157
EVENTS = 'events'
156158
EVENT_ID = 'entity_id'
157159
ATTRIBUTES = 'attributes'
@@ -233,30 +235,17 @@ def _get_required_params_for_impression(self, experiment, variation_id):
233235

234236
return snapshot
235237

236-
def _get_required_params_for_conversion(self, event_key, event_tags, decisions):
238+
def _get_required_params_for_conversion(self, event_key, event_tags):
237239
""" Get parameters that are required for the conversion event to register.
238240
239241
Args:
240242
event_key: Key representing the event which needs to be recorded.
241243
event_tags: Dict representing metadata associated with the event.
242-
decisions: List of tuples representing valid experiments IDs and variation IDs.
243244
244245
Returns:
245246
Dict consisting of the decisions and events info for conversion event.
246247
"""
247248
snapshot = {}
248-
snapshot[self.EventParams.DECISIONS] = []
249-
250-
for experiment_id, variation_id in decisions:
251-
252-
experiment = self.config.get_experiment_from_id(experiment_id)
253-
254-
if variation_id:
255-
snapshot[self.EventParams.DECISIONS].append({
256-
self.EventParams.EXPERIMENT_ID: experiment_id,
257-
self.EventParams.VARIATION_ID: variation_id,
258-
self.EventParams.CAMPAIGN_ID: experiment.layerId
259-
})
260249

261250
event_dict = {
262251
self.EventParams.EVENT_ID: self.config.get_event(event_key).id,
@@ -303,22 +292,21 @@ def create_impression_event(self, experiment, variation_id, user_id, attributes)
303292
http_verb=self.HTTP_VERB,
304293
headers=self.HTTP_HEADERS)
305294

306-
def create_conversion_event(self, event_key, user_id, attributes, event_tags, decisions):
295+
def create_conversion_event(self, event_key, user_id, attributes, event_tags):
307296
""" Create conversion Event to be sent to the logging endpoint.
308297
309298
Args:
310299
event_key: Key representing the event which needs to be recorded.
311300
user_id: ID for user.
312301
attributes: Dict representing user attributes and values.
313302
event_tags: Dict representing metadata associated with the event.
314-
decisions: List of tuples representing experiments IDs and variation IDs.
315303
316304
Returns:
317305
Event object encapsulating the conversion event.
318306
"""
319307

320308
params = self._get_common_params(user_id, attributes)
321-
conversion_params = self._get_required_params_for_conversion(event_key, event_tags, decisions)
309+
conversion_params = self._get_required_params_for_conversion(event_key, event_tags)
322310

323311
params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(conversion_params)
324312
return Event(self.EVENTS_URL,

optimizely/optimizely.py

Lines changed: 13 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2016-2018, Optimizely
1+
# Copyright 2016-2019, Optimizely
22
# Licensed under the Apache License, Version 2.0 (the "License");
33
# you may not use this file except in compliance with the License.
44
# You may obtain a copy of the License at
@@ -133,31 +133,6 @@ def _validate_user_inputs(self, attributes=None, event_tags=None):
133133

134134
return True
135135

136-
def _get_decisions(self, event, user_id, attributes):
137-
""" Helper method to retrieve decisions for the user for experiment(s) using the provided event.
138-
139-
Args:
140-
event: The event which needs to be recorded.
141-
user_id: ID for user.
142-
attributes: Dict representing user attributes.
143-
144-
Returns:
145-
List of tuples representing valid experiment IDs and variation IDs into which the user is bucketed.
146-
"""
147-
decisions = []
148-
for experiment_id in event.experimentIds:
149-
experiment = self.config.get_experiment_from_id(experiment_id)
150-
variation_key = self.get_variation(experiment.key, user_id, attributes)
151-
152-
if not variation_key:
153-
self.logger.info('Not tracking user "%s" for experiment "%s".' % (user_id, experiment.key))
154-
continue
155-
156-
variation = self.config.get_variation_from_key(experiment.key, variation_key)
157-
decisions.append((experiment_id, variation.id))
158-
159-
return decisions
160-
161136
def _send_impression_event(self, experiment, variation, user_id, attributes):
162137
""" Helper method to send impression event.
163138
@@ -322,28 +297,18 @@ def track(self, event_key, user_id, attributes=None, event_tags=None):
322297
self.logger.info('Not tracking user "%s" for event "%s".' % (user_id, event_key))
323298
return
324299

325-
# Filter out experiments that are not running or that do not include the user in audience
326-
# conditions and then determine the decision i.e. the corresponding variation
327-
decisions = self._get_decisions(event, user_id, attributes)
328-
329-
# Create and dispatch conversion event if there are any decisions
330-
if decisions:
331-
conversion_event = self.event_builder.create_conversion_event(
332-
event_key, user_id, attributes, event_tags, decisions
333-
)
334-
self.logger.info('Tracking event "%s" for user "%s".' % (event_key, user_id))
335-
self.logger.debug('Dispatching conversion event to URL %s with params %s.' % (
336-
conversion_event.url,
337-
conversion_event.params
338-
))
339-
try:
340-
self.event_dispatcher.dispatch_event(conversion_event)
341-
except:
342-
self.logger.exception('Unable to dispatch conversion event!')
343-
self.notification_center.send_notifications(enums.NotificationTypes.TRACK, event_key, user_id,
344-
attributes, event_tags, conversion_event)
345-
else:
346-
self.logger.info('There are no valid experiments for event "%s" to track.' % event_key)
300+
conversion_event = self.event_builder.create_conversion_event(event_key, user_id, attributes, event_tags)
301+
self.logger.info('Tracking event "%s" for user "%s".' % (event_key, user_id))
302+
self.logger.debug('Dispatching conversion event to URL %s with params %s.' % (
303+
conversion_event.url,
304+
conversion_event.params
305+
))
306+
try:
307+
self.event_dispatcher.dispatch_event(conversion_event)
308+
except:
309+
self.logger.exception('Unable to dispatch conversion event!')
310+
self.notification_center.send_notifications(enums.NotificationTypes.TRACK, event_key, user_id,
311+
attributes, event_tags, conversion_event)
347312

348313
def get_variation(self, experiment_key, user_id, attributes=None):
349314
""" Gets variation where user will be bucketed.

0 commit comments

Comments
 (0)