1111
1212from ._featurefilters import FeatureFilter
1313
14- FEATURE_FLAG_NAME_KEY = "name "
14+ FEATURE_FLAG_NAME_KEY = "feature_name "
1515ROLLOUT_PERCENTAGE_KEY = "RolloutPercentage"
1616DEFAULT_ROLLOUT_PERCENTAGE_KEY = "DefaultRolloutPercentage"
1717PARAMETERS_KEY = "parameters"
3535
3636class TargetingException (Exception ):
3737 """
38- Exception raised when the targeting filter is not configured correctly
38+ Exception raised when the targeting filter is not configured correctly.
3939 """
4040
4141
4242@FeatureFilter .alias ("Microsoft.TimeWindow" )
4343class TimeWindowFilter (FeatureFilter ):
4444 """
45- Feature Filter that determines if the current time is within the time window
45+ Feature Filter that determines if the current time is within the time window.
4646 """
4747
4848 def evaluate (self , context , ** kwargs ):
4949 """
50- Determine if the feature flag is enabled for the given context
50+ Determine if the feature flag is enabled for the given context.
5151
52- :keyword Mapping context: Mapping with the Start and End time for the feature flag
53- :paramtype context: Mapping
54- :return: True if the current time is within the time window
52+ :keyword Mapping context: Mapping with the Start and End time for the feature flag.
53+ :return: True if the current time is within the time window.
5554 :rtype: bool
5655 """
5756 start = context .get (PARAMETERS_KEY , {}).get (START_KEY )
@@ -72,7 +71,7 @@ def evaluate(self, context, **kwargs):
7271@FeatureFilter .alias ("Microsoft.Targeting" )
7372class TargetingFilter (FeatureFilter ):
7473 """
75- Feature Filter that determines if the user is targeted for the feature flag
74+ Feature Filter that determines if the user is targeted for the feature flag.
7675 """
7776
7877 @staticmethod
@@ -82,27 +81,26 @@ def _is_targeted(context_id, rollout_percentage):
8281 if rollout_percentage == 100 :
8382 return True
8483
85- hashed_context_id = hashlib .sha256 (context_id .encode ()).hexdigest ()
86- context_marker = abs (int (hashed_context_id , 16 ))
87- percentage = (context_marker / (2 ** 256 - 1 )) * 100
84+ hashed_context_id = hashlib .sha256 (context_id .encode ()).digest ()
85+ context_marker = int .from_bytes (hashed_context_id [:4 ], byteorder = "little" , signed = False )
8886
87+ percentage = (context_marker / (2 ** 32 - 1 )) * 100
8988 return percentage < rollout_percentage
9089
9190 def _target_group (self , target_user , target_group , group , feature_flag_name ):
9291 group_rollout_percentage = group .get (ROLLOUT_PERCENTAGE_KEY , 0 )
93- audience_context_id = (
94- target_user + " \n " + target_group + " \n " + feature_flag_name + " \n " + group . get ( FEATURE_FILTER_NAME_KEY , "" )
95- )
92+ if not target_user :
93+ target_user = ""
94+ audience_context_id = target_user + " \n " + feature_flag_name + " \n " + target_group
9695
9796 return self ._is_targeted (audience_context_id , group_rollout_percentage )
9897
9998 def evaluate (self , context , ** kwargs ):
10099 """
101- Determine if the feature flag is enabled for the given context
100+ Determine if the feature flag is enabled for the given context.
102101
103- :keyword Mapping context: Context for evaluating the user/group
104- :paramtype context: Mapping
105- :return: True if the user is targeted for the feature flag
102+ :keyword Mapping context: Context for evaluating the user/group.
103+ :return: True if the user is targeted for the feature flag.
106104 :rtype: bool
107105 """
108106 target_user = kwargs .get (TARGETED_USER_KEY , None )
@@ -129,7 +127,7 @@ def evaluate(self, context, **kwargs):
129127
130128 # Check if the user is in an excluded group
131129 for group in audience .get (EXCLUSION_KEY , {}).get (GROUPS_KEY , []):
132- if group . get ( FEATURE_FILTER_NAME_KEY ) in target_groups :
130+ if group in target_groups :
133131 return False
134132
135133 # Check if the user is targeted
@@ -147,6 +145,8 @@ def evaluate(self, context, **kwargs):
147145 if self ._target_group (target_user , target_group , group , feature_flag_name ):
148146 return True
149147
148+ if not target_user :
149+ target_user = ""
150150 # Check if the user is in the default rollout
151151 context_id = target_user + "\n " + feature_flag_name
152152 return self ._is_targeted (context_id , default_rollout_percentage )
0 commit comments