Skip to content

Commit

Permalink
feat: features notification listener
Browse files Browse the repository at this point in the history
  • Loading branch information
rashidsp committed Feb 15, 2019
1 parent a6709f2 commit 02db55a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
42 changes: 42 additions & 0 deletions optimizely/event_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,27 @@ def _get_required_params_for_conversion(self, event_key, event_tags):
snapshot[self.EventParams.EVENTS] = [event_dict]
return snapshot

def _get_required_params_for_feature(self, feature_key):
""" Get parameters that are required for the feature event to register.
Args:
feature_key: Key representing the feature which needs to be recorded.
Returns:
Dict consisting of the decisions and events info for feature event.
"""
snapshot = {}

event_dict = {
self.EventParams.EVENT_ID: self.config.get_feature_from_key(feature_key).id,
self.EventParams.TIME: self._get_time(),
self.EventParams.KEY: feature_key,
self.EventParams.UUID: str(uuid.uuid4())
}

snapshot[self.EventParams.EVENTS] = [event_dict]
return snapshot

def create_impression_event(self, experiment, variation_id, user_id, attributes):
""" Create impression Event to be sent to the logging endpoint.
Expand Down Expand Up @@ -313,3 +334,24 @@ def create_conversion_event(self, event_key, user_id, attributes, event_tags):
params,
http_verb=self.HTTP_VERB,
headers=self.HTTP_HEADERS)

def create_feature_event(self, feature_key, user_id, attributes):
""" Create feature Event to be sent to the logging endpoint.
Args:
feature_key: Key representing the feature which needs to be recorded.
user_id: ID for user.
attributes: Dict representing user attributes and values.
Returns:
Event object encapsulating the feature event.
"""

params = self._get_common_params(user_id, attributes)
feature_params = self._get_required_params_for_feature(feature_key)

params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(feature_params)
return Event(self.EVENTS_URL,
params,
http_verb=self.HTTP_VERB,
headers=self.HTTP_HEADERS)
5 changes: 4 additions & 1 deletion optimizely/helpers/enums.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2016-2018, Optimizely
# Copyright 2016-2019, Optimizely
# 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
Expand Down Expand Up @@ -70,3 +70,6 @@ class NotificationTypes(object):
"""
ACTIVATE = "ACTIVATE:experiment, user_id, attributes, variation, event"
TRACK = "TRACK:event_key, user_id, attributes, event_tags, event"
IS_FEATURE_ENABLED = "IS_FEATURE_ENABLED: feature_key, user_id, attributes, feature_enabled, event"
GET_FEATURE_VARIABLE = "GET_FEATURE_VARIABLE: feature_key, variable_key, user_id, attributes, feature_enabled, "\
"variable_type, variable_value"
19 changes: 18 additions & 1 deletion optimizely/optimizely.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,10 @@ def _get_feature_variable_for_type(self, feature_key, variable_key, variable_typ
)
return None

feature_enabled = False
decision = self.decision_service.get_variation_for_feature(feature_flag, user_id, attributes)
if decision.variation:
feature_enabled = decision.variation.featureEnabled
variable_value = self.config.get_variable_value_for_variation(variable, decision.variation)

else:
Expand All @@ -225,6 +227,10 @@ def _get_feature_variable_for_type(self, feature_key, variable_key, variable_typ
self.logger.error('Unable to cast value. Returning None.')
actual_value = None

self.notification_center.send_notifications(
enums.NotificationTypes.GET_FEATURE_VARIABLE,
feature_key, variable_key, user_id, attributes, feature_enabled, actual_value, variable_type
)
return actual_value

def activate(self, experiment_key, user_id, attributes=None):
Expand Down Expand Up @@ -384,20 +390,31 @@ def is_feature_enabled(self, feature_key, user_id, attributes=None):
if not feature:
return False

feature_enabled = False
feature_event = None
decision = self.decision_service.get_variation_for_feature(feature, user_id, attributes)
if decision.variation:
# Send event if Decision came from an experiment.
if decision.source == decision_service.DECISION_SOURCE_EXPERIMENT:
feature_event = self.event_builder.create_feature_event(feature_key, user_id, attributes)
self._send_impression_event(decision.experiment,
decision.variation,
user_id,
attributes)

if decision.variation.featureEnabled:
feature_enabled = True
self.logger.info('Feature "%s" is enabled for user "%s".' % (feature_key, user_id))
return True

self.logger.info('Feature "%s" is not enabled for user "%s".' % (feature_key, user_id))
self.notification_center.send_notifications(
enums.NotificationTypes.IS_FEATURE_ENABLED,
feature_key,
user_id,
attributes,
feature_enabled,
feature_event
)
return False

def get_enabled_features(self, user_id, attributes=None):
Expand Down

0 comments on commit 02db55a

Please sign in to comment.