diff --git a/optimizely/entities.py b/optimizely/entities.py index 5fcb1b0c..e03158ec 100644 --- a/optimizely/entities.py +++ b/optimizely/entities.py @@ -58,22 +58,6 @@ def __init__(self, id, key, status, audienceIds, variations, forcedVariations, self.groupPolicy = groupPolicy -class FeatureFlag(BaseEntity): - - class Type(object): - BOOLEAN = 'boolean' - DOUBLE = 'double' - INTEGER = 'integer' - STRING = 'string' - - - def __init__(self, id, key, type, defaultValue, **kwargs): - self.id = id - self.key = key - self.type = type - self.defaultValue = defaultValue - - class Group(BaseEntity): def __init__(self, id, policy, experiments, trafficAllocation, **kwargs): @@ -85,8 +69,6 @@ def __init__(self, id, policy, experiments, trafficAllocation, **kwargs): class Variation(BaseEntity): - def __init__(self, id, key, variables=None, featureFlagMap=None, **kwargs): + def __init__(self, id, key, **kwargs): self.id = id self.key = key - self.variables = variables or [] - self.featureFlagMap = featureFlagMap or {} diff --git a/optimizely/project_config.py b/optimizely/project_config.py index 4b55d7e7..09ec7a7a 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -53,7 +53,6 @@ def __init__(self, datafile, logger, error_handler): self.events = config.get('events', []) self.attributes = config.get('attributes', []) self.audiences = config.get('audiences', []) - self.feature_flags = config.get('variables', []) # Utility maps for quick lookup self.group_id_map = self._generate_key_map(self.groups, 'id', entities.Group) @@ -61,7 +60,6 @@ def __init__(self, datafile, logger, error_handler): self.event_key_map = self._generate_key_map(self.events, 'key', entities.Event) self.attribute_key_map = self._generate_key_map(self.attributes, 'key', entities.Attribute) self.audience_id_map = self._generate_key_map(self.audiences, 'id', entities.Audience) - self.feature_flag_id_map = self._generate_key_map(self.feature_flags, 'id', entities.FeatureFlag) self.audience_id_map = self._deserialize_audience(self.audience_id_map) for group in self.group_id_map.values(): experiments_in_group_key_map = self._generate_key_map(group.experiments, 'key', entities.Experiment) @@ -82,8 +80,6 @@ def __init__(self, datafile, logger, error_handler): ) self.variation_id_map[experiment.key] = {} for variation in self.variation_key_map.get(experiment.key).values(): - feature_flag_to_value_map = self._map_feature_flag_to_value(variation.variables, self.feature_flag_id_map) - variation.featureFlagMap = feature_flag_to_value_map self.variation_id_map[experiment.key][variation.id] = variation self.parsing_succeeded = True @@ -127,46 +123,6 @@ def _deserialize_audience(audience_map): return audience_map - def _get_typecast_value(self, value, type): - """ Helper method to determine actual value based on type of feature flag. - - Args: - value: Value in string form as it was parsed from datafile. - type: Type denoting the feature flag type. - - Return: - Value type-casted based on type of feature flag. - """ - - if type == entities.FeatureFlag.Type.BOOLEAN: - return value == 'true' - elif type == entities.FeatureFlag.Type.INTEGER: - return int(value) - elif type == entities.FeatureFlag.Type.DOUBLE: - return float(value) - else: - return value - - def _map_feature_flag_to_value(self, variables, feature_flag_id_map): - """ Helper method to create map of feature flag key to associated value for a given variation's feature flag set. - - Args: - variables: List of dicts representing variables on an instance of Variation object. - feature_flag_id_map: Dict mapping feature flag key to feature flag object. - - Returns: - Dict mapping values from feature flag key to value stored on the variation's variable. - """ - - feature_flag_value_map = {} - for variable in variables: - feature_flag = feature_flag_id_map[variable.get('id')] - if not feature_flag: - continue - feature_flag_value_map[feature_flag.key] = self._get_typecast_value(variable.get('value'), feature_flag.type) - - return feature_flag_value_map - def was_parsing_successful(self): """ Helper method to determine if parsing the datafile was successful. diff --git a/tests/test_config.py b/tests/test_config.py index a60c30c8..5b549d2e 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -159,8 +159,8 @@ def test_init(self): self.assertEqual(expected_variation_key_map, self.project_config.variation_key_map) self.assertEqual(expected_variation_id_map, self.project_config.variation_id_map) - def test_init__with_v3_datafile(self): - """ Test that on creating object, properties are initiated correctly for version 3 datafile. """ + def test_init__with_more_fields(self): + """ Test that no issues occur on creating object with datafile consisting of more fields. """ # Adding some additional fields like live variables and IP anonymization config_dict = { @@ -172,21 +172,6 @@ def test_init__with_v3_datafile(self): 'key': 'is_working', 'defaultValue': 'true', 'type': 'boolean', - }, { - 'id': '128', - 'key': 'environment', - 'defaultValue': 'devel', - 'type': 'string', - }, { - 'id': '129', - 'key': 'number_of_days', - 'defaultValue': '192', - 'type': 'integer', - }, { - 'id': '130', - 'key': 'significance_value', - 'defaultValue': '0.00098', - 'type': 'double', }], 'events': [{ 'key': 'test_event', @@ -245,29 +230,11 @@ def test_init__with_v3_datafile(self): 'variations': [{ 'key': 'group_exp_1_control', 'id': '28901', - 'variables': [{ - 'id': '128', - 'value': 'prod' - }, { - 'id': '129', - 'value': '1772' - }, { - 'id': '130', - 'value': '1.22992' - }] + 'variables': [] }, { 'key': 'group_exp_1_variation', 'id': '28902', - 'variables': [{ - 'id': '128', - 'value': 'stage' - }, { - 'id': '129', - 'value': '112' - }, { - 'id': '130', - 'value': '1.211' - }] + 'variables': [] }], 'forcedVariations': { 'user_1': 'group_exp_1_control', @@ -330,197 +297,7 @@ def test_init__with_v3_datafile(self): } test_obj = optimizely.Optimizely(json.dumps(config_dict)) - project_config = test_obj.config - self.assertEqual(config_dict['accountId'], project_config.account_id) - self.assertEqual(config_dict['projectId'], project_config.project_id) - self.assertEqual(config_dict['revision'], project_config.revision) - self.assertEqual(config_dict['experiments'], project_config.experiments) - self.assertEqual(config_dict['events'], project_config.events) - self.assertEqual(config_dict['variables'], project_config.feature_flags) - - expected_group_id_map = { - '19228': entities.Group( - config_dict['groups'][0]['id'], - config_dict['groups'][0]['policy'], - config_dict['groups'][0]['experiments'], - config_dict['groups'][0]['trafficAllocation'] - ) - } - expected_experiment_key_map = { - 'test_experiment': entities.Experiment( - '111127', 'test_experiment', 'Running', ['11154'], [{ - 'key': 'control', - 'id': '111128', - 'variables': [{ - 'id': '127', - 'value': 'false' - }] - }, { - 'key': 'variation', - 'id': '111129', - 'variables': [{ - 'id': '127', - 'value': 'true' - }] - }], { - 'user_1': 'control', - 'user_2': 'control' - }, [{ - 'entityId': '111128', - 'endOfRange': 4000 - }, { - 'entityId': '', - 'endOfRange': 5000 - }, { - 'entityId': '111129', - 'endOfRange': 9000 - }], - '111182'), - 'group_exp_1': entities.Experiment( - '32222', 'group_exp_1', 'Running', [], [{ - 'key': 'group_exp_1_control', - 'id': '28901', - 'variables': [{ - 'id': '128', - 'value': 'prod' - }, { - 'id': '129', - 'value': '1772' - }, { - 'id': '130', - 'value': '1.22992' - }] - }, { - 'key': 'group_exp_1_variation', - 'id': '28902', - 'variables': [{ - 'id': '128', - 'value': 'stage' - }, { - 'id': '129', - 'value': '112' - }, { - 'id': '130', - 'value': '1.211' - }] - }], { - 'user_1': 'group_exp_1_control', - 'user_2': 'group_exp_1_control' - }, [{ - 'entityId': '28901', - 'endOfRange': 3000 - }, { - 'entityId': '28902', - 'endOfRange': 9000 - }], '111183', groupId='19228', groupPolicy='random' - ), - 'group_exp_2': entities.Experiment( - '32223', 'group_exp_2', 'Running', [], [{ - 'key': 'group_exp_2_control', - 'id': '28905', - 'variables': [] - }, { - 'key': 'group_exp_2_variation', - 'id': '28906', - 'variables': [] - }], { - 'user_1': 'group_exp_2_control', - 'user_2': 'group_exp_2_control' - }, [{ - 'entityId': '28905', - 'endOfRange': 8000 - }, { - 'entityId': '28906', - 'endOfRange': 10000 - }], '111184', groupId='19228', groupPolicy='random' - ), - } - expected_experiment_id_map = { - '111127': expected_experiment_key_map.get('test_experiment'), - '32222': expected_experiment_key_map.get('group_exp_1'), - '32223': expected_experiment_key_map.get('group_exp_2') - } - expected_event_key_map = { - 'test_event': entities.Event('111095', 'test_event', ['111127']), - 'Total Revenue': entities.Event('111096', 'Total Revenue', ['111127']) - } - expected_attribute_key_map = { - 'test_attribute': entities.Attribute('111094', 'test_attribute', segmentId='11133') - } - expected_audience_id_map = { - '11154': entities.Audience( - '11154', 'Test attribute users', - '["and", ["or", ["or", {"name": "test_attribute", "type": "custom_attribute", "value": "test_value"}]]]', - conditionStructure=['and', ['or', ['or', 0]]], - conditionList=[['test_attribute', 'test_value']] - ) - } - expected_variation_key_map = { - 'test_experiment': { - 'control': entities.Variation('111128', 'control', [{'id': '127', 'value': 'false'}], {'is_working': False}), - 'variation': entities.Variation('111129', 'variation', [{'id': '127', 'value': 'true'}], {'is_working': True}) - }, - 'group_exp_1': { - 'group_exp_1_control': entities.Variation( - '28901', 'group_exp_1_control', [ - {'id': '128', 'value': 'prod'}, {'id': '129', 'value': '1772'}, {'id': '130', 'value': '1.22992'}], { - 'environment': 'prod', - 'number_of_days': 1772, - 'significance_value': 1.22992 - }), - 'group_exp_1_variation': entities.Variation( - '28902', 'group_exp_1_variation', [ - {'id': '128', 'value': 'stage'}, {'id': '129', 'value': '112'}, {'id': '130', 'value': '1.211'}], { - 'environment': 'stage', - 'number_of_days': 112, - 'significance_value': 1.211 - }) - }, - 'group_exp_2': { - 'group_exp_2_control': entities.Variation('28905', 'group_exp_2_control'), - 'group_exp_2_variation': entities.Variation('28906', 'group_exp_2_variation') - } - } - expected_variation_id_map = { - 'test_experiment': { - '111128': entities.Variation('111128', 'control', [{'id': '127', 'value': 'false'}], {'is_working': False}), - '111129': entities.Variation('111129', 'variation', [{'id': '127', 'value': 'true'}], {'is_working': True}) - }, - 'group_exp_1': { - '28901': entities.Variation('28901', 'group_exp_1_control', [ - {'id': '128', 'value': 'prod'}, {'id': '129', 'value': '1772'}, {'id': '130', 'value': '1.22992'}], { - 'environment': 'prod', - 'number_of_days': 1772, - 'significance_value': 1.22992 - }), - '28902': entities.Variation('28902', 'group_exp_1_variation', [ - {'id': '128', 'value': 'stage'}, {'id': '129', 'value': '112'}, {'id': '130', 'value': '1.211'}], { - 'environment': 'stage', - 'number_of_days': 112, - 'significance_value': 1.211 - }) - }, - 'group_exp_2': { - '28905': entities.Variation('28905', 'group_exp_2_control'), - '28906': entities.Variation('28906', 'group_exp_2_variation') - } - } - expected_feature_flag_id_map = { - '127': entities.FeatureFlag('127', 'is_working', 'boolean', 'true'), - '128': entities.FeatureFlag('128', 'environment', 'string', 'devel'), - '129': entities.FeatureFlag('129', 'number_of_days', 'integer', '192'), - '130': entities.FeatureFlag('130', 'significance_value', 'double', '0.00098') - } - - self.assertEqual(expected_group_id_map, project_config.group_id_map) - self.assertEqual(expected_experiment_key_map, project_config.experiment_key_map) - self.assertEqual(expected_experiment_id_map, project_config.experiment_id_map) - self.assertEqual(expected_event_key_map, project_config.event_key_map) - self.assertEqual(expected_attribute_key_map, project_config.attribute_key_map) - self.assertEqual(expected_audience_id_map, project_config.audience_id_map) - self.assertEqual(expected_variation_key_map, project_config.variation_key_map) - self.assertEqual(expected_variation_id_map, project_config.variation_id_map) - self.assertEqual(expected_feature_flag_id_map, project_config.feature_flag_id_map) + self.assertTrue(test_obj.is_valid) def test_get_version(self): """ Test that JSON version is retrieved correctly when using get_version. """