2323from flag_engine .segments .types import (
2424 ConditionOperator ,
2525 ContextValue ,
26+ FeatureMetadataT ,
2627 SegmentMetadataT ,
2728 is_context_value ,
2829)
3233from flag_engine .utils .types import SupportsStr , get_casting_function
3334
3435
35- class FeatureContextWithSegmentName (typing .TypedDict ):
36- feature_context : FeatureContext
36+ class FeatureContextWithSegmentName (typing .TypedDict , typing . Generic [ FeatureMetadataT ] ):
37+ feature_context : FeatureContext [ FeatureMetadataT ]
3738 segment_name : str
3839
3940
4041def get_evaluation_result (
41- context : EvaluationContext [SegmentMetadataT ],
42- ) -> EvaluationResult [SegmentMetadataT ]:
42+ context : EvaluationContext [SegmentMetadataT , FeatureMetadataT ],
43+ ) -> EvaluationResult [SegmentMetadataT , FeatureMetadataT ]:
4344 """
4445 Get the evaluation result for a given context.
4546
4647 :param context: the evaluation context
4748 :return: EvaluationResult containing the context, flags, and segments
4849 """
4950 segments : list [SegmentResult [SegmentMetadataT ]] = []
50- flags : dict [str , FlagResult ] = {}
51+ flags : dict [str , FlagResult [ FeatureMetadataT ] ] = {}
5152
52- segment_feature_contexts : dict [SupportsStr , FeatureContextWithSegmentName ] = {}
53+ segment_feature_contexts : dict [
54+ SupportsStr ,
55+ FeatureContextWithSegmentName [FeatureMetadataT ],
56+ ] = {}
5357
5458 for segment_context in (context .get ("segments" ) or {}).values ():
5559 if not is_context_in_segment (context , segment_context ):
@@ -59,8 +63,8 @@ def get_evaluation_result(
5963 "key" : segment_context ["key" ],
6064 "name" : segment_context ["name" ],
6165 }
62- if metadata := segment_context .get ("metadata" ):
63- segment_result ["metadata" ] = metadata
66+ if segment_metadata := segment_context .get ("metadata" ):
67+ segment_result ["metadata" ] = segment_metadata
6468 segments .append (segment_result )
6569
6670 if overrides := segment_context .get ("overrides" ):
@@ -95,13 +99,16 @@ def get_evaluation_result(
9599 feature_context ["feature_key" ],
96100 ):
97101 feature_context = feature_context_with_segment_name ["feature_context" ]
98- flags [feature_name ] = {
102+ flag_result : FlagResult [FeatureMetadataT ]
103+ flags [feature_name ] = flag_result = {
99104 "enabled" : feature_context ["enabled" ],
100105 "feature_key" : feature_context ["feature_key" ],
101106 "name" : feature_context ["name" ],
102107 "reason" : f"TARGETING_MATCH; segment={ feature_context_with_segment_name ['segment_name' ]} " ,
103108 "value" : feature_context .get ("value" ),
104109 }
110+ if feature_metadata := feature_context .get ("metadata" ):
111+ flag_result ["metadata" ] = feature_metadata
105112 continue
106113 flags [feature_name ] = get_flag_result_from_feature_context (
107114 feature_context = feature_context ,
@@ -115,9 +122,9 @@ def get_evaluation_result(
115122
116123
117124def get_flag_result_from_feature_context (
118- feature_context : FeatureContext ,
125+ feature_context : FeatureContext [ FeatureMetadataT ] ,
119126 key : typing .Optional [SupportsStr ],
120- ) -> FlagResult :
127+ ) -> FlagResult [ FeatureMetadataT ] :
121128 """
122129 Get a feature value from the feature context
123130 for a given key.
@@ -126,6 +133,8 @@ def get_flag_result_from_feature_context(
126133 :param key: the key to get the value for
127134 :return: the value for the key in the feature context
128135 """
136+ flag_result : typing .Optional [FlagResult [FeatureMetadataT ]] = None
137+
129138 if key is not None and (variants := feature_context .get ("variants" )):
130139 percentage_value = get_hashed_percentage_for_object_ids (
131140 [feature_context ["key" ], key ]
@@ -139,28 +148,35 @@ def get_flag_result_from_feature_context(
139148 ):
140149 limit = (weight := variant ["weight" ]) + start_percentage
141150 if start_percentage <= percentage_value < limit :
142- return {
151+ flag_result = {
143152 "enabled" : feature_context ["enabled" ],
144153 "feature_key" : feature_context ["feature_key" ],
145154 "name" : feature_context ["name" ],
146155 "reason" : f"SPLIT; weight={ weight } " ,
147156 "value" : variant ["value" ],
148157 }
158+ break
149159
150160 start_percentage = limit
151161
152- return {
153- "enabled" : feature_context ["enabled" ],
154- "feature_key" : feature_context ["feature_key" ],
155- "name" : feature_context ["name" ],
156- "reason" : "DEFAULT" ,
157- "value" : feature_context ["value" ],
158- }
162+ if flag_result is None :
163+ flag_result = {
164+ "enabled" : feature_context ["enabled" ],
165+ "feature_key" : feature_context ["feature_key" ],
166+ "name" : feature_context ["name" ],
167+ "reason" : "DEFAULT" ,
168+ "value" : feature_context ["value" ],
169+ }
170+
171+ if metadata := feature_context .get ("metadata" ):
172+ flag_result ["metadata" ] = metadata
173+
174+ return flag_result
159175
160176
161177def is_context_in_segment (
162- context : EvaluationContext [SegmentMetadataT ],
163- segment_context : SegmentContext [SegmentMetadataT ],
178+ context : EvaluationContext [typing . Any , typing . Any ],
179+ segment_context : SegmentContext [typing . Any , typing . Any ],
164180) -> bool :
165181 return bool (rules := segment_context ["rules" ]) and all (
166182 context_matches_rule (
@@ -171,7 +187,7 @@ def is_context_in_segment(
171187
172188
173189def context_matches_rule (
174- context : EvaluationContext [SegmentMetadataT ],
190+ context : EvaluationContext [typing . Any , typing . Any ],
175191 rule : SegmentRule ,
176192 segment_key : SupportsStr ,
177193) -> bool :
@@ -201,7 +217,7 @@ def context_matches_rule(
201217
202218
203219def context_matches_condition (
204- context : EvaluationContext [SegmentMetadataT ],
220+ context : EvaluationContext [typing . Any , typing . Any ],
205221 condition : SegmentCondition ,
206222 segment_key : SupportsStr ,
207223) -> bool :
@@ -262,7 +278,7 @@ def context_matches_condition(
262278
263279
264280def get_context_value (
265- context : EvaluationContext [SegmentMetadataT ],
281+ context : EvaluationContext [typing . Any , typing . Any ],
266282 property : str ,
267283) -> ContextValue :
268284 value = None
0 commit comments