Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added enabled field to decision metadata #306

Merged
merged 1 commit into from
Nov 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion optimizely/event/event_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def _create_visitor(cls, event, logger):
experiment_layerId = event.experiment.layerId
experiment_id = event.experiment.id

metadata = payload.Metadata(event.flag_key, event.rule_key, event.rule_type, variation_key)
metadata = payload.Metadata(event.flag_key, event.rule_key, event.rule_type, variation_key, event.enabled)
decision = payload.Decision(experiment_layerId, experiment_id, variation_id, metadata)
snapshot_event = payload.SnapshotEvent(
experiment_layerId, event.uuid, cls.ACTIVATE_EVENT_KEY, event.timestamp,
Expand Down
3 changes: 2 additions & 1 deletion optimizely/event/payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,12 @@ def __init__(self, campaign_id, experiment_id, variation_id, metadata):
class Metadata(object):
""" Class respresenting Metadata. """

def __init__(self, flag_key, rule_key, rule_type, variation_key):
def __init__(self, flag_key, rule_key, rule_type, variation_key, enabled):
self.flag_key = flag_key
self.rule_key = rule_key
self.rule_type = rule_type
self.variation_key = variation_key
self.enabled = enabled


class Snapshot(object):
Expand Down
5 changes: 3 additions & 2 deletions optimizely/event/user_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,16 @@ class ImpressionEvent(UserEvent):
""" Class representing Impression Event. """

def __init__(
self, event_context, user_id, experiment, visitor_attributes, variation, flag_key, rule_key, rule_type,
bot_filtering=None,
self, event_context, user_id, experiment, visitor_attributes, variation, flag_key,
rule_key, rule_type, enabled, bot_filtering=None
):
super(ImpressionEvent, self).__init__(event_context, user_id, visitor_attributes, bot_filtering)
self.experiment = experiment
self.variation = variation
self.flag_key = flag_key
self.rule_key = rule_key
self.rule_type = rule_type
self.enabled = enabled


class ConversionEvent(UserEvent):
Expand Down
5 changes: 4 additions & 1 deletion optimizely/event/user_event_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class UserEventFactory(object):

@classmethod
def create_impression_event(
cls, project_config, activated_experiment, variation_id, flag_key, rule_key, rule_type, user_id, user_attributes
cls, project_config, activated_experiment, variation_id, flag_key, rule_key, rule_type,
enabled, user_id, user_attributes
):
""" Create impression Event to be sent to the logging endpoint.

Expand All @@ -32,6 +33,7 @@ def create_impression_event(
flag_key: key for a feature flag.
rule_key: key for an experiment.
rule_type: type for the source.
enabled: boolean representing if feature is enabled
user_id: ID for user.
attributes: Dict representing user attributes and values which need to be recorded.

Expand Down Expand Up @@ -62,6 +64,7 @@ def create_impression_event(
flag_key,
rule_key,
rule_type,
enabled,
project_config.get_bot_filtering_value(),
)

Expand Down
38 changes: 20 additions & 18 deletions optimizely/optimizely.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ def _validate_user_inputs(self, attributes=None, event_tags=None):

return True

def _send_impression_event(self, project_config, experiment, variation, flag_key, rule_key, rule_type, user_id,
attributes):
def _send_impression_event(self, project_config, experiment, variation, flag_key, rule_key, rule_type, enabled,
user_id, attributes):
""" Helper method to send impression event.

Args:
Expand All @@ -171,12 +171,13 @@ def _send_impression_event(self, project_config, experiment, variation, flag_key
flag_key: key for a feature flag.
rule_key: key for an experiment.
rule_type: type for the source.
enabled: boolean representing if feature is enabled
user_id: ID for user.
attributes: Dict representing user attributes and values which need to be recorded.
"""
variation_id = variation.id if variation is not None else None
user_event = user_event_factory.UserEventFactory.create_impression_event(
project_config, experiment, variation_id, flag_key, rule_key, rule_type, user_id, attributes
project_config, experiment, variation_id, flag_key, rule_key, rule_type, enabled, user_id, attributes
)

self.event_processor.process(user_event)
Expand Down Expand Up @@ -427,7 +428,7 @@ def activate(self, experiment_key, user_id, attributes=None):
# Create and dispatch impression event
self.logger.info('Activating user "%s" in experiment "%s".' % (user_id, experiment.key))
self._send_impression_event(project_config, experiment, variation, '', experiment.key,
enums.DecisionSources.EXPERIMENT, user_id, attributes)
enums.DecisionSources.EXPERIMENT, True, user_id, attributes)

return variation.key

Expand Down Expand Up @@ -580,25 +581,26 @@ def is_feature_enabled(self, feature_key, user_id, attributes=None):
is_source_experiment = decision.source == enums.DecisionSources.FEATURE_TEST
is_source_rollout = decision.source == enums.DecisionSources.ROLLOUT

if decision.variation:
if decision.variation.featureEnabled is True:
feature_enabled = True

if (is_source_rollout or not decision.variation) and project_config.get_send_flag_decisions_value():
self._send_impression_event(
project_config, decision.experiment, decision.variation, feature.key, decision.experiment.key if
decision.experiment else '', decision.source, user_id, attributes
decision.experiment else '', decision.source, feature_enabled, user_id, attributes
)

if decision.variation:
if decision.variation.featureEnabled is True:
feature_enabled = True
# Send event if Decision came from an experiment.
if is_source_experiment:
source_info = {
'experiment_key': decision.experiment.key,
'variation_key': decision.variation.key,
}
self._send_impression_event(
project_config, decision.experiment, decision.variation, feature.key, decision.experiment.key,
decision.source, user_id, attributes
)
# Send event if Decision came from an experiment.
if is_source_experiment and decision.variation:
source_info = {
'experiment_key': decision.experiment.key,
'variation_key': decision.variation.key,
}
self._send_impression_event(
project_config, decision.experiment, decision.variation, feature.key, decision.experiment.key,
decision.source, feature_enabled, user_id, attributes
)

if feature_enabled:
self.logger.info('Feature "%s" is enabled for user "%s".' % (feature_key, user_id))
Expand Down
24 changes: 18 additions & 6 deletions tests/test_event_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ def test_create_impression_event(self):
'metadata': {'flag_key': 'flag_key',
'rule_key': 'rule_key',
'rule_type': 'experiment',
'variation_key': 'variation'}}
'variation_key': 'variation',
'enabled': False}}
],
'events': [
{
Expand Down Expand Up @@ -109,6 +110,7 @@ def test_create_impression_event(self):
'flag_key',
'rule_key',
'experiment',
False,
'test_user',
None,
)
Expand Down Expand Up @@ -139,7 +141,8 @@ def test_create_impression_event__with_attributes(self):
'metadata': {'flag_key': 'flag_key',
'rule_key': 'rule_key',
'rule_type': 'experiment',
'variation_key': 'variation'},
'variation_key': 'variation',
'enabled': True},
}
],
'events': [
Expand Down Expand Up @@ -171,6 +174,7 @@ def test_create_impression_event__with_attributes(self):
'flag_key',
'rule_key',
'experiment',
True,
'test_user',
{'test_attribute': 'test_value'},
)
Expand Down Expand Up @@ -199,7 +203,8 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self):
'metadata': {'flag_key': 'flag_key',
'rule_key': 'rule_key',
'rule_type': 'experiment',
'variation_key': 'variation'}
'variation_key': 'variation',
'enabled': True}
}
],
'events': [
Expand Down Expand Up @@ -231,6 +236,7 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self):
'flag_key',
'rule_key',
'experiment',
True,
'test_user',
{'do_you_know_me': 'test_value'},
)
Expand Down Expand Up @@ -350,7 +356,8 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled(
'metadata': {'flag_key': 'flag_key',
'rule_key': 'rule_key',
'rule_type': 'experiment',
'variation_key': 'variation'},
'variation_key': 'variation',
'enabled': False},
}
],
'events': [
Expand Down Expand Up @@ -384,6 +391,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled(
'flag_key',
'rule_key',
'experiment',
False,
'test_user',
{'$opt_user_agent': 'Edge'},
)
Expand Down Expand Up @@ -420,7 +428,8 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en
'metadata': {'flag_key': 'flag_key',
'rule_key': 'rule_key',
'rule_type': 'experiment',
'variation_key': 'variation'},
'variation_key': 'variation',
'enabled': False},
}
],
'events': [
Expand Down Expand Up @@ -454,6 +463,7 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en
'flag_key',
'rule_key',
'experiment',
False,
'test_user',
None,
)
Expand Down Expand Up @@ -496,7 +506,8 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled
'metadata': {'flag_key': 'flag_key',
'rule_key': 'rule_key',
'rule_type': 'experiment',
'variation_key': 'variation'},
'variation_key': 'variation',
'enabled': True},
}
],
'events': [
Expand Down Expand Up @@ -530,6 +541,7 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled
'flag_key',
'rule_key',
'experiment',
True,
'test_user',
{'$opt_user_agent': 'Chrome'},
)
Expand Down
5 changes: 3 additions & 2 deletions tests/test_event_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ def test_impression_event_equals_serialized_payload(self):
'metadata': {'flag_key': 'flag_key',
'rule_key': 'rule_key',
'rule_type': 'experiment',
'variation_key': 'variation'},
'variation_key': 'variation',
'enabled': False},
}
],
'events': [
Expand All @@ -59,7 +60,7 @@ def test_impression_event_equals_serialized_payload(self):
batch = payload.EventBatch('12001', '111001', '42', 'python-sdk', version.__version__, False, True)
visitor_attr = payload.VisitorAttribute('111094', 'test_attribute', 'custom', 'test_value')
event = payload.SnapshotEvent('111182', 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c', 'campaign_activated', 42123,)
metadata = payload.Metadata('flag_key', 'rule_key', 'experiment', 'variation')
metadata = payload.Metadata('flag_key', 'rule_key', 'experiment', 'variation', False)
event_decision = payload.Decision('111182', '111127', '111129', metadata)

snapshots = payload.Snapshot([event], [event_decision])
Expand Down
24 changes: 16 additions & 8 deletions tests/test_optimizely.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,8 @@ def test_activate(self):
'metadata': {'flag_key': '',
'rule_key': 'test_experiment',
'rule_type': 'experiment',
'variation_key': 'variation'},
'variation_key': 'variation',
'enabled': True},
}
],
'events': [
Expand Down Expand Up @@ -703,7 +704,8 @@ def test_activate__with_attributes__audience_match(self):
'metadata': {'flag_key': '',
'rule_key': 'test_experiment',
'rule_type': 'experiment',
'variation_key': 'variation'},
'variation_key': 'variation',
'enabled': True},
}
],
'events': [
Expand Down Expand Up @@ -785,7 +787,8 @@ def test_activate__with_attributes_of_different_types(self):
'metadata': {'flag_key': '',
'rule_key': 'test_experiment',
'rule_type': 'experiment',
'variation_key': 'variation'},
'variation_key': 'variation',
'enabled': True},
}
],
'events': [
Expand Down Expand Up @@ -981,7 +984,8 @@ def test_activate__with_attributes__audience_match__forced_bucketing(self):
'metadata': {'flag_key': '',
'rule_key': 'test_experiment',
'rule_type': 'experiment',
'variation_key': 'control'},
'variation_key': 'control',
'enabled': True},
}
],
'events': [
Expand Down Expand Up @@ -1056,7 +1060,8 @@ def test_activate__with_attributes__audience_match__bucketing_id_provided(self):
'metadata': {'flag_key': '',
'rule_key': 'test_experiment',
'rule_type': 'experiment',
'variation_key': 'variation'},
'variation_key': 'variation',
'enabled': True},
}
],
'events': [
Expand Down Expand Up @@ -2004,7 +2009,8 @@ def test_is_feature_enabled__returns_true_for_feature_experiment_if_feature_enab
'metadata': {'flag_key': 'test_feature_in_experiment',
'rule_key': 'test_experiment',
'rule_type': 'feature-test',
'variation_key': 'variation'}}
'variation_key': 'variation',
'enabled': True}}
],
'events': [
{
Expand Down Expand Up @@ -2102,7 +2108,8 @@ def test_is_feature_enabled__returns_false_for_feature_experiment_if_feature_dis
'metadata': {'flag_key': 'test_feature_in_experiment',
'rule_key': 'test_experiment',
'rule_type': 'feature-test',
'variation_key': 'control'}}
'variation_key': 'control',
'enabled': False}}
],
'events': [
{
Expand Down Expand Up @@ -2248,7 +2255,8 @@ def test_is_feature_enabled__returns_true_for_feature_rollout_if_feature_enabled
'metadata': {'flag_key': 'test_feature_in_experiment',
'rule_key': 'test_experiment',
'rule_type': 'rollout',
'variation_key': 'variation'},
'variation_key': 'variation',
'enabled': True},
}
],
'events': [
Expand Down
4 changes: 2 additions & 2 deletions tests/test_user_event_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_impression_event(self):
user_id = 'test_user'

impression_event = UserEventFactory.create_impression_event(project_config, experiment, '111128', 'flag_key',
'rule_key', 'rule_type', user_id, None)
'rule_key', 'rule_type', True, user_id, None)

self.assertEqual(self.project_config.project_id, impression_event.event_context.project_id)
self.assertEqual(self.project_config.revision, impression_event.event_context.revision)
Expand All @@ -51,7 +51,7 @@ def test_impression_event__with_attributes(self):
user_attributes = {'test_attribute': 'test_value', 'boolean_key': True}

impression_event = UserEventFactory.create_impression_event(
project_config, experiment, '111128', 'flag_key', 'rule_key', 'rule_type', user_id, user_attributes
project_config, experiment, '111128', 'flag_key', 'rule_key', 'rule_type', True, user_id, user_attributes
)

expected_attrs = EventFactory.build_attribute_list(user_attributes, project_config)
Expand Down