Skip to content

Commit

Permalink
Merge 18a3644 into beba5e3
Browse files Browse the repository at this point in the history
  • Loading branch information
aliabbasrizvi committed Jan 8, 2019
2 parents beba5e3 + 18a3644 commit 53470ff
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 203 deletions.
22 changes: 5 additions & 17 deletions optimizely/event_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def _get_common_params(self, user_id, attributes):
commonParams[self.EventParams.USERS][0][self.EventParams.ATTRIBUTES] = self._get_attributes(attributes)

commonParams[self.EventParams.SOURCE_SDK_TYPE] = 'python-sdk'
commonParams[self.EventParams.ENRICH_DECISIONS] = True
commonParams[self.EventParams.SOURCE_SDK_VERSION] = version.__version__
commonParams[self.EventParams.ANONYMIZE_IP] = self._get_anonymize_ip()
commonParams[self.EventParams.REVISION] = self._get_revision()
Expand All @@ -152,6 +153,7 @@ class EventParams(object):
CAMPAIGN_ID = 'campaign_id'
VARIATION_ID = 'variation_id'
END_USER_ID = 'visitor_id'
ENRICH_DECISIONS = 'enrich_decisions'
EVENTS = 'events'
EVENT_ID = 'entity_id'
ATTRIBUTES = 'attributes'
Expand Down Expand Up @@ -233,30 +235,17 @@ def _get_required_params_for_impression(self, experiment, variation_id):

return snapshot

def _get_required_params_for_conversion(self, event_key, event_tags, decisions):
def _get_required_params_for_conversion(self, event_key, event_tags):
""" Get parameters that are required for the conversion event to register.
Args:
event_key: Key representing the event which needs to be recorded.
event_tags: Dict representing metadata associated with the event.
decisions: List of tuples representing valid experiments IDs and variation IDs.
Returns:
Dict consisting of the decisions and events info for conversion event.
"""
snapshot = {}
snapshot[self.EventParams.DECISIONS] = []

for experiment_id, variation_id in decisions:

experiment = self.config.get_experiment_from_id(experiment_id)

if variation_id:
snapshot[self.EventParams.DECISIONS].append({
self.EventParams.EXPERIMENT_ID: experiment_id,
self.EventParams.VARIATION_ID: variation_id,
self.EventParams.CAMPAIGN_ID: experiment.layerId
})

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

def create_conversion_event(self, event_key, user_id, attributes, event_tags, decisions):
def create_conversion_event(self, event_key, user_id, attributes, event_tags):
""" Create conversion Event to be sent to the logging endpoint.
Args:
event_key: Key representing the event which needs to be recorded.
user_id: ID for user.
attributes: Dict representing user attributes and values.
event_tags: Dict representing metadata associated with the event.
decisions: List of tuples representing experiments IDs and variation IDs.
Returns:
Event object encapsulating the conversion event.
"""

params = self._get_common_params(user_id, attributes)
conversion_params = self._get_required_params_for_conversion(event_key, event_tags, decisions)
conversion_params = self._get_required_params_for_conversion(event_key, event_tags)

params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(conversion_params)
return Event(self.EVENTS_URL,
Expand Down
34 changes: 12 additions & 22 deletions optimizely/optimizely.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,28 +322,18 @@ def track(self, event_key, user_id, attributes=None, event_tags=None):
self.logger.info('Not tracking user "%s" for event "%s".' % (user_id, event_key))
return

# Filter out experiments that are not running or that do not include the user in audience
# conditions and then determine the decision i.e. the corresponding variation
decisions = self._get_decisions(event, user_id, attributes)

# Create and dispatch conversion event if there are any decisions
if decisions:
conversion_event = self.event_builder.create_conversion_event(
event_key, user_id, attributes, event_tags, decisions
)
self.logger.info('Tracking event "%s" for user "%s".' % (event_key, user_id))
self.logger.debug('Dispatching conversion event to URL %s with params %s.' % (
conversion_event.url,
conversion_event.params
))
try:
self.event_dispatcher.dispatch_event(conversion_event)
except:
self.logger.exception('Unable to dispatch conversion event!')
self.notification_center.send_notifications(enums.NotificationTypes.TRACK, event_key, user_id,
attributes, event_tags, conversion_event)
else:
self.logger.info('There are no valid experiments for event "%s" to track.' % event_key)
conversion_event = self.event_builder.create_conversion_event(event_key, user_id, attributes, event_tags)
self.logger.info('Tracking event "%s" for user "%s".' % (event_key, user_id))
self.logger.debug('Dispatching conversion event to URL %s with params %s.' % (
conversion_event.url,
conversion_event.params
))
try:
self.event_dispatcher.dispatch_event(conversion_event)
except:
self.logger.exception('Unable to dispatch conversion event!')
self.notification_center.send_notifications(enums.NotificationTypes.TRACK, event_key, user_id,
attributes, event_tags, conversion_event)

def get_variation(self, experiment_key, user_id, attributes=None):
""" Gets variation where user will be bucketed.
Expand Down
72 changes: 22 additions & 50 deletions tests/test_event_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def test_create_impression_event(self):
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand Down Expand Up @@ -131,6 +132,7 @@ def test_create_impression_event__with_attributes(self):
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand Down Expand Up @@ -173,6 +175,7 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self):
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand Down Expand Up @@ -225,6 +228,7 @@ def test_create_impression_event_calls_is_attribute_valid(self):
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand Down Expand Up @@ -295,6 +299,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled(
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand Down Expand Up @@ -345,6 +350,7 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand Down Expand Up @@ -400,6 +406,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand Down Expand Up @@ -429,11 +436,6 @@ def test_create_conversion_event(self):
'visitor_id': 'test_user',
'attributes': [],
'snapshots': [{
'decisions': [{
'variation_id': '111129',
'experiment_id': '111127',
'campaign_id': '111182'
}],
'events': [{
'timestamp': 42123,
'entity_id': '111095',
Expand All @@ -444,14 +446,15 @@ def test_create_conversion_event(self):
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}

with mock.patch('time.time', return_value=42.123), \
mock.patch('uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'):
event_obj = self.event_builder.create_conversion_event(
'test_event', 'test_user', None, None, [('111127', '111129')]
'test_event', 'test_user', None, None
)
self._validate_event_object(event_obj,
event_builder.EventBuilder.EVENTS_URL,
Expand All @@ -475,11 +478,6 @@ def test_create_conversion_event__with_attributes(self):
'key': 'test_attribute'
}],
'snapshots': [{
'decisions': [{
'variation_id': '111129',
'experiment_id': '111127',
'campaign_id': '111182'
}],
'events': [{
'timestamp': 42123,
'entity_id': '111095',
Expand All @@ -490,14 +488,15 @@ def test_create_conversion_event__with_attributes(self):
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}

with mock.patch('time.time', return_value=42.123), \
mock.patch('uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'):
event_obj = self.event_builder.create_conversion_event(
'test_event', 'test_user', {'test_attribute': 'test_value'}, None, [('111127', '111129')]
'test_event', 'test_user', {'test_attribute': 'test_value'}, None
)
self._validate_event_object(event_obj,
event_builder.EventBuilder.EVENTS_URL,
Expand Down Expand Up @@ -527,11 +526,6 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled(
'key': '$opt_bot_filtering'
}],
'snapshots': [{
'decisions': [{
'variation_id': '111129',
'experiment_id': '111127',
'campaign_id': '111182'
}],
'events': [{
'timestamp': 42123,
'entity_id': '111095',
Expand All @@ -542,6 +536,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled(
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand All @@ -550,7 +545,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled(
mock.patch('uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'), \
mock.patch('optimizely.event_builder.EventBuilder._get_bot_filtering', return_value=True):
event_obj = self.event_builder.create_conversion_event(
'test_event', 'test_user', {'$opt_user_agent': 'Edge'}, None, [('111127', '111129')]
'test_event', 'test_user', {'$opt_user_agent': 'Edge'}, None
)

self._validate_event_object(event_obj,
Expand Down Expand Up @@ -581,11 +576,6 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled
'key': '$opt_bot_filtering'
}],
'snapshots': [{
'decisions': [{
'variation_id': '111129',
'experiment_id': '111127',
'campaign_id': '111182'
}],
'events': [{
'timestamp': 42123,
'entity_id': '111095',
Expand All @@ -596,6 +586,7 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled
}],
'client_name': 'python-sdk',
'client_version': version.__version__,
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand All @@ -604,8 +595,8 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled
mock.patch('uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'), \
mock.patch('optimizely.event_builder.EventBuilder._get_bot_filtering', return_value=False):
event_obj = self.event_builder.create_conversion_event(
'test_event', 'test_user', {'$opt_user_agent': 'Chrome'}, None, [('111127', '111129')]
)
'test_event', 'test_user', {'$opt_user_agent': 'Chrome'}, None
)

self._validate_event_object(event_obj,
event_builder.EventBuilder.EVENTS_URL,
Expand All @@ -629,11 +620,6 @@ def test_create_conversion_event__with_event_tags(self):
}],
'visitor_id': 'test_user',
'snapshots': [{
'decisions': [{
'variation_id': '111129',
'experiment_id': '111127',
'campaign_id': '111182'
}],
'events': [{
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'tags': {
Expand All @@ -651,6 +637,7 @@ def test_create_conversion_event__with_event_tags(self):
}],
'account_id': '12001',
'client_name': 'python-sdk',
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand All @@ -661,8 +648,7 @@ def test_create_conversion_event__with_event_tags(self):
'test_event',
'test_user',
{'test_attribute': 'test_value'},
{'revenue': 4200, 'value': 1.234, 'non-revenue': 'abc'},
[('111127', '111129')]
{'revenue': 4200, 'value': 1.234, 'non-revenue': 'abc'}
)
self._validate_event_object(event_obj,
event_builder.EventBuilder.EVENTS_URL,
Expand All @@ -686,11 +672,6 @@ def test_create_conversion_event__with_invalid_event_tags(self):
}],
'visitor_id': 'test_user',
'snapshots': [{
'decisions': [{
'variation_id': '111129',
'experiment_id': '111127',
'campaign_id': '111182'
}],
'events': [{
'timestamp': 42123,
'entity_id': '111095',
Expand All @@ -706,6 +687,7 @@ def test_create_conversion_event__with_invalid_event_tags(self):
}],
'account_id': '12001',
'client_name': 'python-sdk',
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand All @@ -716,8 +698,7 @@ def test_create_conversion_event__with_invalid_event_tags(self):
'test_event',
'test_user',
{'test_attribute': 'test_value'},
{'revenue': '4200', 'value': True, 'non-revenue': 'abc'},
[('111127', '111129')]
{'revenue': '4200', 'value': True, 'non-revenue': 'abc'}
)
self._validate_event_object(event_obj,
event_builder.EventBuilder.EVENTS_URL,
Expand All @@ -741,15 +722,6 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel
}],
'visitor_id': 'test_user',
'snapshots': [{
'decisions': [{
'variation_id': '111129',
'experiment_id': '111127',
'campaign_id': '111182'
}, {
'experiment_id': '111130',
'variation_id': '111131',
'campaign_id': '111182'
}],
'events': [{
'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c',
'tags': {
Expand All @@ -767,6 +739,7 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel
}],
'account_id': '12001',
'client_name': 'python-sdk',
'enrich_decisions': True,
'anonymize_ip': False,
'revision': '42'
}
Expand All @@ -777,8 +750,7 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel
'test_event',
'test_user',
{'test_attribute': 'test_value'},
{'revenue': 4200, 'value': 1.234, 'non-revenue': 'abc'},
[('111127', '111129'), ('111130', '111131')]
{'revenue': 4200, 'value': 1.234, 'non-revenue': 'abc'}
)
self._validate_event_object(event_obj,
event_builder.EventBuilder.EVENTS_URL,
Expand Down
Loading

0 comments on commit 53470ff

Please sign in to comment.