1616from six import string_types
1717
1818from . import bucketer
19+ from .decision .optimizely_decide_option import OptimizelyDecideOption
1920from .helpers import audience as audience_helper
2021from .helpers import enums
2122from .helpers import experiment as experiment_helper
2223from .helpers import validator
2324from .optimizely_user_context import OptimizelyUserContext
24- from .decision .optimizely_decide_option import OptimizelyDecideOption
2525from .user_profile import UserProfile
2626
2727Decision = namedtuple ('Decision' , 'experiment variation source' )
@@ -44,14 +44,14 @@ def __init__(self, logger, user_profile_service):
4444 def _get_bucketing_id (self , user_id , attributes ):
4545 """ Helper method to determine bucketing ID for the user.
4646
47- Args:
48- user_id: ID for user.
49- attributes: Dict representing user attributes. May consist of bucketing ID to be used.
47+ Args:
48+ user_id: ID for user.
49+ attributes: Dict representing user attributes. May consist of bucketing ID to be used.
5050
51- Returns:
52- String representing bucketing ID if it is a String type in attributes else return user ID
53- array of log messages representing decision making.
54- """
51+ Returns:
52+ String representing bucketing ID if it is a String type in attributes else return user ID
53+ array of log messages representing decision making.
54+ """
5555 decide_reasons = []
5656 attributes = attributes or {}
5757 bucketing_id = attributes .get (enums .ControlAttributes .BUCKETING_ID )
@@ -68,15 +68,15 @@ def _get_bucketing_id(self, user_id, attributes):
6868 def set_forced_variation (self , project_config , experiment_key , user_id , variation_key ):
6969 """ Sets users to a map of experiments to forced variations.
7070
71- Args:
72- project_config: Instance of ProjectConfig.
73- experiment_key: Key for experiment.
74- user_id: The user ID.
75- variation_key: Key for variation. If None, then clear the existing experiment-to-variation mapping.
71+ Args:
72+ project_config: Instance of ProjectConfig.
73+ experiment_key: Key for experiment.
74+ user_id: The user ID.
75+ variation_key: Key for variation. If None, then clear the existing experiment-to-variation mapping.
7676
77- Returns:
78- A boolean value that indicates if the set completed successfully.
79- """
77+ Returns:
78+ A boolean value that indicates if the set completed successfully.
79+ """
8080 experiment = project_config .get_experiment_from_key (experiment_key )
8181 if not experiment :
8282 # The invalid experiment key will be logged inside this call.
@@ -126,15 +126,15 @@ def set_forced_variation(self, project_config, experiment_key, user_id, variatio
126126 def get_forced_variation (self , project_config , experiment_key , user_id ):
127127 """ Gets the forced variation key for the given user and experiment.
128128
129- Args:
130- project_config: Instance of ProjectConfig.
131- experiment_key: Key for experiment.
132- user_id: The user ID.
129+ Args:
130+ project_config: Instance of ProjectConfig.
131+ experiment_key: Key for experiment.
132+ user_id: The user ID.
133133
134- Returns:
135- The variation which the given user and experiment should be forced into and
136- array of log messages representing decision making.
137- """
134+ Returns:
135+ The variation which the given user and experiment should be forced into and
136+ array of log messages representing decision making.
137+ """
138138 decide_reasons = []
139139 if user_id not in self .forced_variation_map :
140140 message = 'User "%s" is not in the forced variation map.' % user_id
@@ -174,15 +174,15 @@ def get_whitelisted_variation(self, project_config, experiment, user_id):
174174 """ Determine if a user is forced into a variation (through whitelisting)
175175 for the given experiment and return that variation.
176176
177- Args:
178- project_config: Instance of ProjectConfig.
179- experiment: Object representing the experiment for which user is to be bucketed.
180- user_id: ID for the user.
177+ Args:
178+ project_config: Instance of ProjectConfig.
179+ experiment: Object representing the experiment for which user is to be bucketed.
180+ user_id: ID for the user.
181181
182- Returns:
183- Variation in which the user with ID user_id is forced into. None if no variation and
184- array of log messages representing decision making.
185- """
182+ Returns:
183+ Variation in which the user with ID user_id is forced into. None if no variation and
184+ array of log messages representing decision making.
185+ """
186186 decide_reasons = []
187187 forced_variations = experiment .forcedVariations
188188
@@ -202,14 +202,14 @@ def get_whitelisted_variation(self, project_config, experiment, user_id):
202202 def get_stored_variation (self , project_config , experiment , user_profile ):
203203 """ Determine if the user has a stored variation available for the given experiment and return that.
204204
205- Args:
206- project_config: Instance of ProjectConfig.
207- experiment: Object representing the experiment for which user is to be bucketed.
208- user_profile: UserProfile object representing the user's profile.
205+ Args:
206+ project_config: Instance of ProjectConfig.
207+ experiment: Object representing the experiment for which user is to be bucketed.
208+ user_profile: UserProfile object representing the user's profile.
209209
210- Returns:
211- Variation if available. None otherwise.
212- """
210+ Returns:
211+ Variation if available. None otherwise.
212+ """
213213 user_id = user_profile .user_id
214214 variation_id = user_profile .get_variation_for_experiment (experiment .id )
215215
@@ -228,22 +228,22 @@ def get_stored_variation(self, project_config, experiment, user_profile):
228228 def get_variation (self , project_config , experiment , user_context , options = None ):
229229 """ Top-level function to help determine variation user should be put in.
230230
231- First, check if experiment is running.
232- Second, check if user is forced in a variation.
233- Third, check if there is a stored decision for the user and return the corresponding variation.
234- Fourth, figure out if user is in the experiment by evaluating audience conditions if any.
235- Fifth, bucket the user and return the variation.
236-
237- Args:
238- project_config: Instance of ProjectConfig.
239- experiment: Experiment for which user variation needs to be determined.
240- user_context: contains user id and attributes
241- options: Decide options.
242-
243- Returns:
244- Variation user should see. None if user is not in experiment or experiment is not running
245- And an array of log messages representing decision making.
246- """
231+ First, check if experiment is running.
232+ Second, check if user is forced in a variation.
233+ Third, check if there is a stored decision for the user and return the corresponding variation.
234+ Fourth, figure out if user is in the experiment by evaluating audience conditions if any.
235+ Fifth, bucket the user and return the variation.
236+
237+ Args:
238+ project_config: Instance of ProjectConfig.
239+ experiment: Experiment for which user variation needs to be determined.
240+ user_context: contains user id and attributes
241+ options: Decide options.
242+
243+ Returns:
244+ Variation user should see. None if user is not in experiment or experiment is not running
245+ And an array of log messages representing decision making.
246+ """
247247 user_id = user_context .user_id
248248 attributes = user_context .get_user_attributes ()
249249
@@ -333,21 +333,21 @@ def get_variation(self, project_config, experiment, user_context, options=None):
333333 decide_reasons .append (message )
334334 return None , decide_reasons
335335
336- def get_variation_for_rollout (self , project_config , feature , user , options ):
336+ def get_variation_for_rollout (self , project_config , feature , user ):
337337 """ Determine which experiment/variation the user is in for a given rollout.
338338 Returns the variation of the first experiment the user qualifies for.
339339
340- Args:
341- project_config: Instance of ProjectConfig.
342- flagKey: Feature key.
343- rollout: Rollout for which we are getting the variation.
344- user: ID and attributes for user.
345- options: Decide options.
340+ Args:
341+ project_config: Instance of ProjectConfig.
342+ flagKey: Feature key.
343+ rollout: Rollout for which we are getting the variation.
344+ user: ID and attributes for user.
345+ options: Decide options.
346346
347- Returns:
348- Decision namedtuple consisting of experiment and variation for the user and
349- array of log messages representing decision making.
350- """
347+ Returns:
348+ Decision namedtuple consisting of experiment and variation for the user and
349+ array of log messages representing decision making.
350+ """
351351 decide_reasons = []
352352
353353 if not feature or not feature .rolloutId :
@@ -366,8 +366,7 @@ def get_variation_for_rollout(self, project_config, feature, user, options):
366366 while index < len (rollout_rules ):
367367 decision_response , reasons_received = self .get_variation_from_delivery_rule (project_config ,
368368 feature ,
369- rollout_rules , index , user ,
370- options )
369+ rollout_rules , index , user )
371370
372371 decide_reasons += reasons_received
373372
@@ -406,8 +405,7 @@ def get_variation_from_experiment_rule(self, config, flag_key, rule, user, optio
406405 optimizely_decision_context = OptimizelyUserContext .OptimizelyDecisionContext (flag_key , rule .key )
407406
408407 forced_decision_variation , reasons_received = user .find_validated_forced_decision (
409- optimizely_decision_context ,
410- options )
408+ optimizely_decision_context )
411409 decide_reasons += reasons_received
412410
413411 if forced_decision_variation :
@@ -418,7 +416,7 @@ def get_variation_from_experiment_rule(self, config, flag_key, rule, user, optio
418416 decide_reasons += variation_reasons
419417 return decision_variation , decide_reasons
420418
421- def get_variation_from_delivery_rule (self , config , feature , rules , rule_index , user , options ):
419+ def get_variation_from_delivery_rule (self , config , feature , rules , rule_index , user ):
422420 """ Checks for delivery rule if decision is forced and returns it.
423421 Otherwise returns a regular decision.
424422
@@ -428,7 +426,6 @@ def get_variation_from_delivery_rule(self, config, feature, rules, rule_index, u
428426 rules: Experiment rule.
429427 rule_index: integer index of the rule in the list.
430428 user: ID and attributes for user.
431- options: Decide options.
432429
433430 Returns:
434431 If forced decision, it returns namedtuple consisting of forced_decision_variation and skip_to_everyone_else
@@ -444,8 +441,7 @@ def get_variation_from_delivery_rule(self, config, feature, rules, rule_index, u
444441 # check forced decision first
445442 rule = rules [rule_index ]
446443 optimizely_decision_context = OptimizelyUserContext .OptimizelyDecisionContext (feature .key , rule .key )
447- forced_decision_variation , reasons_received = user .find_validated_forced_decision (optimizely_decision_context ,
448- options )
444+ forced_decision_variation , reasons_received = user .find_validated_forced_decision (optimizely_decision_context )
449445
450446 decide_reasons += reasons_received
451447
@@ -504,15 +500,15 @@ def get_variation_from_delivery_rule(self, config, feature, rules, rule_index, u
504500 def get_variation_for_feature (self , project_config , feature , user_context , options = None ):
505501 """ Returns the experiment/variation the user is bucketed in for the given feature.
506502
507- Args:
508- project_config: Instance of ProjectConfig.
509- feature: Feature for which we are determining if it is enabled or not for the given user.
510- user: user context for user.
511- attributes: Dict representing user attributes.
512- options: Decide options.
503+ Args:
504+ project_config: Instance of ProjectConfig.
505+ feature: Feature for which we are determining if it is enabled or not for the given user.
506+ user: user context for user.
507+ attributes: Dict representing user attributes.
508+ options: Decide options.
513509
514- Returns:
515- Decision namedtuple consisting of experiment and variation for the user.
510+ Returns:
511+ Decision namedtuple consisting of experiment and variation for the user.
516512 """
517513 decide_reasons = []
518514
@@ -528,8 +524,4 @@ def get_variation_for_feature(self, project_config, feature, user_context, optio
528524 if variation :
529525 return Decision (experiment , variation , enums .DecisionSources .FEATURE_TEST ), decide_reasons
530526
531- # Next check if user is part of a rollout
532- if feature .rolloutId :
533- return self .get_variation_for_rollout (project_config , feature , user_context , options )
534- else :
535- return Decision (None , None , enums .DecisionSources .ROLLOUT ), decide_reasons
527+ return self .get_variation_for_rollout (project_config , feature , user_context )
0 commit comments