Skip to content

Commit ac7c453

Browse files
committed
Revert "Add feature flag parsing (#57)"
This reverts commit ef0ccdf.
1 parent 574c8f7 commit ac7c453

File tree

4 files changed

+27
-839
lines changed

4 files changed

+27
-839
lines changed

optimizely/entities.py

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,6 @@ def __init__(self, id, key, status, audienceIds, variations, forcedVariations,
5959
self.groupPolicy = groupPolicy
6060

6161

62-
class Feature(BaseEntity):
63-
64-
def __init__(self, id, key, experimentIds, layerId, variables, groupId=None, **kwargs):
65-
self.id = id
66-
self.key = key
67-
self.experimentIds = experimentIds
68-
self.layerId = layerId
69-
self.variables = variables
70-
self.groupId = groupId
71-
72-
7362
class Group(BaseEntity):
7463

7564
def __init__(self, id, policy, experiments, trafficAllocation, **kwargs):
@@ -79,38 +68,10 @@ def __init__(self, id, policy, experiments, trafficAllocation, **kwargs):
7968
self.trafficAllocation = trafficAllocation
8069

8170

82-
class Layer(BaseEntity):
83-
84-
def __init__(self, id, policy, experiments, **kwargs):
85-
self.id = id
86-
self.policy = policy
87-
self.experiments = experiments
88-
89-
90-
class Variable(BaseEntity):
91-
92-
class Type(object):
93-
BOOLEAN = 'boolean'
94-
DOUBLE = 'double'
95-
INTEGER = 'integer'
96-
STRING = 'string'
97-
98-
def __init__(self, id, key, type, defaultValue, **kwargs):
99-
self.id = id
100-
self.key = key
101-
self.type = type
102-
self.defaultValue = defaultValue
103-
104-
10571
class Variation(BaseEntity):
10672

107-
class VariableUsage(BaseEntity):
108-
109-
def __init__(self, id, value, **kwards):
110-
self.id = id
111-
self.value = value
112-
113-
def __init__(self, id, key, variables=None, **kwargs):
73+
def __init__(self, id, key, variables=None, featureFlagMap=None, **kwargs):
11474
self.id = id
11575
self.key = key
11676
self.variables = variables or []
77+
self.featureFlagMap = featureFlagMap or {}

optimizely/project_config.py

Lines changed: 0 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from . import entities
1919
from . import exceptions
2020

21-
REVENUE_GOAL_KEY = 'Total Revenue'
2221
V1_CONFIG_VERSION = '1'
2322
V2_CONFIG_VERSION = '2'
2423

@@ -54,20 +53,13 @@ def __init__(self, datafile, logger, error_handler):
5453
self.attributes = config.get('attributes', [])
5554
self.audiences = config.get('audiences', [])
5655
self.anonymize_ip = config.get('anonymizeIP', False)
57-
self.features = config.get('features', [])
58-
self.layers = config.get('layers', [])
5956

6057
# Utility maps for quick lookup
6158
self.group_id_map = self._generate_key_map(self.groups, 'id', entities.Group)
6259
self.experiment_key_map = self._generate_key_map(self.experiments, 'key', entities.Experiment)
6360
self.event_key_map = self._generate_key_map(self.events, 'key', entities.Event)
6461
self.attribute_key_map = self._generate_key_map(self.attributes, 'key', entities.Attribute)
6562
self.audience_id_map = self._generate_key_map(self.audiences, 'id', entities.Audience)
66-
self.layer_id_map = self._generate_key_map(self.layers, 'id', entities.Layer)
67-
for layer in self.layer_id_map.values():
68-
for experiment in layer.experiments:
69-
self.experiment_key_map[experiment['key']] = entities.Experiment(**experiment)
70-
7163
self.audience_id_map = self._deserialize_audience(self.audience_id_map)
7264
for group in self.group_id_map.values():
7365
experiments_in_group_key_map = self._generate_key_map(group.experiments, 'key', entities.Experiment)
@@ -81,7 +73,6 @@ def __init__(self, datafile, logger, error_handler):
8173
self.experiment_id_map = {}
8274
self.variation_key_map = {}
8375
self.variation_id_map = {}
84-
self.variation_variable_usage_map = {}
8576
for experiment in self.experiment_key_map.values():
8677
self.experiment_id_map[experiment.id] = experiment
8778
self.variation_key_map[experiment.key] = self._generate_key_map(
@@ -90,22 +81,6 @@ def __init__(self, datafile, logger, error_handler):
9081
self.variation_id_map[experiment.key] = {}
9182
for variation in self.variation_key_map.get(experiment.key).values():
9283
self.variation_id_map[experiment.key][variation.id] = variation
93-
if variation.variables:
94-
self.variation_variable_usage_map[variation.id] = self._generate_key_map(
95-
variation.variables, 'id', entities.Variation.VariableUsage
96-
)
97-
98-
self.feature_key_map = self._generate_key_map(self.features, 'key', entities.Feature)
99-
for feature in self.feature_key_map.values():
100-
feature.variables = self._generate_key_map(feature.variables, 'key', entities.Variable)
101-
102-
# Check if any of the experiments are in a group and add the group id for faster bucketing later on
103-
for exp_id in feature.experimentIds:
104-
experiment_in_feature = self.experiment_id_map[exp_id]
105-
if experiment_in_feature.groupId:
106-
feature.groupId = experiment_in_feature.groupId
107-
# Experiments in feature can only belong to one mutex group
108-
break
10984

11085
self.parsing_succeeded = True
11186

@@ -154,26 +129,6 @@ def _deserialize_audience(audience_map):
154129

155130
return audience_map
156131

157-
def _get_typecast_value(self, value, type):
158-
""" Helper method to determine actual value based on type of feature variable.
159-
160-
Args:
161-
value: Value in string form as it was parsed from datafile.
162-
type: Type denoting the feature flag type.
163-
164-
Return:
165-
Value type-casted based on type of feature variable.
166-
"""
167-
168-
if type == entities.Variable.Type.BOOLEAN:
169-
return value == 'true'
170-
elif type == entities.Variable.Type.INTEGER:
171-
return int(value)
172-
elif type == entities.Variable.Type.DOUBLE:
173-
return float(value)
174-
else:
175-
return value
176-
177132
def was_parsing_successful(self):
178133
""" Helper method to determine if parsing the datafile was successful.
179134
@@ -383,87 +338,6 @@ def get_attribute(self, attribute_key):
383338
self.error_handler.handle_error(exceptions.InvalidAttributeException(enums.Errors.INVALID_ATTRIBUTE_ERROR))
384339
return None
385340

386-
def get_feature_from_key(self, feature_key):
387-
""" Get feature for the provided feature key.
388-
389-
Args:
390-
feature_key: Feature key for which feature is to be fetched.
391-
392-
Returns:
393-
Feature corresponding to the provided feature key.
394-
"""
395-
feature = self.feature_key_map.get(feature_key)
396-
397-
if feature:
398-
return feature
399-
400-
self.logger.log(enums.LogLevels.ERROR, 'Feature "%s" is not in datafile.' % feature_key)
401-
return None
402-
403-
def get_layer_from_id(self, layer_id):
404-
""" Get layer for the provided layer id.
405-
406-
Args:
407-
layer_id: ID of the layer to be fetched.
408-
409-
Returns:
410-
Layer corresponding to the provided layer id.
411-
"""
412-
layer = self.layer_id_map.get(layer_id)
413-
414-
if layer:
415-
return layer
416-
417-
self.logger.log(enums.LogLevels.ERROR, 'Layer with ID "%s" is not in datafile.' % layer_id)
418-
return None
419-
420-
def get_variable_value_for_variation(self, variable, variation):
421-
""" Get the variable value for the given variation.
422-
423-
Args:
424-
Variable: The Variable for which we are getting the value.
425-
Variation: The Variation for which we are getting the variable value.
426-
427-
Returns:
428-
The type-casted variable value or None if any of the inputs are invalid.
429-
"""
430-
if not variable or not variation:
431-
return None
432-
433-
if variation.id not in self.variation_variable_usage_map:
434-
self.logger.log(enums.LogLevels.ERROR, 'Variation with ID "%s" is not in the datafile.' % variation.id)
435-
return None
436-
437-
# Get all variable usages for the given variation
438-
variable_usages = self.variation_variable_usage_map[variation.id]
439-
440-
# Find usage in given variation
441-
variable_usage = variable_usages[variable.id]
442-
443-
value = self._get_typecast_value(variable_usage.value, variable.type)
444-
return value
445-
446-
def get_variable_for_feature(self, feature_key, variable_key):
447-
""" Get the variable with the given variable key for the given feature
448-
449-
Args:
450-
feature_key: The key of the feature for which we are getting the variable.
451-
variable_key: The key of the variable we are getting.
452-
453-
Returns:
454-
Variable with the given key in the given variation.
455-
"""
456-
feature = self.feature_key_map.get(feature_key)
457-
if not feature:
458-
self.logger.log(enums.LogLevels.ERROR, 'Feature with key "%s" not found in the datafile.' % feature_key)
459-
return None
460-
461-
if variable_key not in feature.variables:
462-
self.logger.log(enums.LogLevels.ERROR, 'Variable with key "%s" not found in the datafile.' % variable_key)
463-
return None
464-
465-
return feature.variables.get(variable_key)
466-
467341
def set_forced_variation(self, experiment_key, user_id, variation_key):
468342
""" Sets users to a map of experiments to forced variations.
469343

tests/base.py

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -139,106 +139,6 @@ def setUp(self):
139139
'projectId': '111001'
140140
}
141141

142-
# datafile version 4
143-
self.config_dict_with_features = {
144-
'revision': '1',
145-
'accountId': '12001',
146-
'projectId': '111111',
147-
'version': '4',
148-
'events': [{
149-
'key': 'test_event',
150-
'experimentIds': ['111127'],
151-
'id': '111095'
152-
}],
153-
'experiments': [{
154-
'key': 'test_experiment',
155-
'status': 'Running',
156-
'forcedVariations': {},
157-
'layerId': '111182',
158-
'audienceIds': [],
159-
'trafficAllocation': [{
160-
'entityId': '111128',
161-
'endOfRange': 5000
162-
}, {
163-
'entityId': '111129',
164-
'endOfRange': 9000
165-
}],
166-
'id': '111127',
167-
'variations': [{
168-
'key': 'control',
169-
'id': '111128',
170-
'variables': [{
171-
'id': '127', 'value': 'false'
172-
}, {
173-
'id': '128', 'value': 'prod'
174-
}]
175-
}, {
176-
'key': 'variation',
177-
'id': '111129'
178-
}]
179-
}],
180-
'groups': [],
181-
'attributes': [{
182-
'key': 'test_attribute',
183-
'id': '111094'
184-
}],
185-
'audiences': [{
186-
'name': 'Test attribute users',
187-
'conditions': '["and", ["or", ["or", '
188-
'{"name": "test_attribute", "type": "custom_attribute", "value": "test_value"}]]]',
189-
'id': '11154'
190-
}],
191-
'layers': [{
192-
'id': '211111',
193-
'policy': 'ordered',
194-
'experiments': [{
195-
'key': 'test_rollout_exp_1',
196-
'status': 'Running',
197-
'forcedVariations': {},
198-
'layerId': '211111',
199-
'audienceIds': ['11154'],
200-
'trafficAllocation': [{
201-
'entityId': '211128',
202-
'endOfRange': 5000
203-
}, {
204-
'entityId': '211129',
205-
'endOfRange': 9000
206-
}],
207-
'id': '211127',
208-
'variations': [{
209-
'key': 'control',
210-
'id': '211128'
211-
}, {
212-
'key': 'variation',
213-
'id': '211129'
214-
}]
215-
}]
216-
}],
217-
'features': [{
218-
'id': '91111',
219-
'key': 'test_feature_1',
220-
'experimentIds': ['111127'],
221-
'layerId': '',
222-
'variables': [{
223-
'id': '127',
224-
'key': 'is_working',
225-
'defaultValue': 'true',
226-
'type': 'boolean',
227-
}, {
228-
'id': '128',
229-
'key': 'environment',
230-
'defaultValue': 'devel',
231-
'type': 'string',
232-
}]
233-
}, {
234-
'id': '91112',
235-
'key': 'test_feature_2',
236-
'experimentIds': [],
237-
'layerId': '211111',
238-
'variables': [],
239-
}]
240-
}
241-
242142
self.optimizely = optimizely.Optimizely(json.dumps(self.config_dict))
243143
self.project_config = self.optimizely.config
244144

0 commit comments

Comments
 (0)