@@ -287,6 +287,97 @@ def _get_feature_variable_for_type(
287287 )
288288 return actual_value
289289
290+ def _get_all_feature_variables_for_type (
291+ self , project_config , feature_key , user_id , attributes ,
292+ ):
293+ """ Helper method to determine value for all variables attached to a feature flag.
294+
295+ Args:
296+ project_config: Instance of ProjectConfig.
297+ feature_key: Key of the feature whose variable's value is being accessed.
298+ user_id: ID for user.
299+ attributes: Dict representing user attributes.
300+
301+ Returns:
302+ Dictionary of all variables. None if:
303+ - Feature key is invalid.
304+ """
305+ if not validator .is_non_empty_string (feature_key ):
306+ self .logger .error (enums .Errors .INVALID_INPUT .format ('feature_key' ))
307+ return None
308+
309+ if not isinstance (user_id , string_types ):
310+ self .logger .error (enums .Errors .INVALID_INPUT .format ('user_id' ))
311+ return None
312+
313+ if not self ._validate_user_inputs (attributes ):
314+ return None
315+
316+ feature_flag = project_config .get_feature_from_key (feature_key )
317+ if not feature_flag :
318+ return None
319+
320+ feature_enabled = False
321+ source_info = {}
322+
323+ decision = self .decision_service .get_variation_for_feature (project_config , feature_flag , user_id , attributes )
324+ if decision .variation :
325+
326+ feature_enabled = decision .variation .featureEnabled
327+ if feature_enabled :
328+ self .logger .info (
329+ 'Feature "%s" for variation "%s" is enabled.' % (feature_key , decision .variation .key )
330+ )
331+ else :
332+ self .logger .info (
333+ 'Feature "%s" for variation "%s" is not enabled.' % (feature_key , decision .variation .key )
334+ )
335+ else :
336+ self .logger .info (
337+ 'User "%s" is not in any variation or rollout rule. '
338+ 'Returning default value for all variables of feature flag "%s".' % (user_id , feature_key )
339+ )
340+
341+ all_variables = {}
342+ for variable_key in feature_flag .variables :
343+ variable = project_config .get_variable_for_feature (feature_key , variable_key )
344+ variable_value = variable .defaultValue
345+ if feature_enabled :
346+ variable_value = project_config .get_variable_value_for_variation (variable , decision .variation )
347+ self .logger .debug (
348+ 'Got variable value "%s" for variable "%s" of feature flag "%s".'
349+ % (variable_value , variable_key , feature_key )
350+ )
351+
352+ try :
353+ actual_value = project_config .get_typecast_value (variable_value , variable .type )
354+ except :
355+ self .logger .error ('Unable to cast value. Returning None.' )
356+ actual_value = None
357+
358+ all_variables [variable_key ] = actual_value
359+
360+ if decision .source == enums .DecisionSources .FEATURE_TEST :
361+ source_info = {
362+ 'experiment_key' : decision .experiment .key ,
363+ 'variation_key' : decision .variation .key ,
364+ }
365+
366+ self .notification_center .send_notifications (
367+ enums .NotificationTypes .DECISION ,
368+ enums .DecisionNotificationTypes .ALL_FEATURE_VARIABLES ,
369+ user_id ,
370+ attributes or {},
371+ {
372+ 'feature_key' : feature_key ,
373+ 'feature_enabled' : feature_enabled ,
374+ 'variable_values' : all_variables ,
375+ 'source' : decision .source ,
376+ 'source_info' : source_info ,
377+ },
378+ )
379+ return all_variables
380+
290381 def activate (self , experiment_key , user_id , attributes = None ):
291382 """ Buckets visitor and sends impression event to Optimizely.
292383
@@ -672,6 +763,54 @@ def get_feature_variable_string(self, feature_key, variable_key, user_id, attrib
672763 project_config , feature_key , variable_key , variable_type , user_id , attributes ,
673764 )
674765
766+ def get_feature_variable_json (self , feature_key , variable_key , user_id , attributes = None ):
767+ """ Returns value for a certain JSON variable attached to a feature.
768+
769+ Args:
770+ feature_key: Key of the feature whose variable's value is being accessed.
771+ variable_key: Key of the variable whose value is to be accessed.
772+ user_id: ID for user.
773+ attributes: Dict representing user attributes.
774+
775+ Returns:
776+ Dictionary object of the variable. None if:
777+ - Feature key is invalid.
778+ - Variable key is invalid.
779+ - Mismatch with type of variable.
780+ """
781+
782+ variable_type = entities .Variable .Type .JSON
783+ project_config = self .config_manager .get_config ()
784+ if not project_config :
785+ self .logger .error (enums .Errors .INVALID_PROJECT_CONFIG .format ('get_feature_variable_json' ))
786+ return None
787+
788+ return self ._get_feature_variable_for_type (
789+ project_config , feature_key , variable_key , variable_type , user_id , attributes ,
790+ )
791+
792+ def get_all_feature_variables (self , feature_key , user_id , attributes = None ):
793+ """ Returns dictionary of all variables and their corresponding values in the context of a feature.
794+
795+ Args:
796+ feature_key: Key of the feature whose variable's value is being accessed.
797+ user_id: ID for user.
798+ attributes: Dict representing user attributes.
799+
800+ Returns:
801+ Dictionary mapping variable key to variable value. None if:
802+ - Feature key is invalid.
803+ """
804+
805+ project_config = self .config_manager .get_config ()
806+ if not project_config :
807+ self .logger .error (enums .Errors .INVALID_PROJECT_CONFIG .format ('get_all_feature_variables' ))
808+ return None
809+
810+ return self ._get_all_feature_variables_for_type (
811+ project_config , feature_key , user_id , attributes ,
812+ )
813+
675814 def set_forced_variation (self , experiment_key , user_id , variation_key ):
676815 """ Force a user into a variation for a given experiment.
677816
0 commit comments