Skip to content

Commit ed0f59e

Browse files
runtime rule NO MATCH ✅
1 parent cfa2de7 commit ed0f59e

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

‎mixpanel/flags/local_feature_flags.py‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,26 @@ def _get_assigned_rollout(
312312
rollout_hash = normalized_hash(str(context_value), salt)
313313

314314
if (rollout_hash < rollout.rollout_percentage
315-
and self._is_runtime_evaluation_satisfied(rollout, context)
315+
and self._is_runtime_rules_engine_satisfied(rollout, context)
316316
):
317317
return rollout
318318

319319
return None
320+
321+
def _is_runtime_rules_engine_satisfied(self, rollout: Rollout, context: Dict[str, Any]) -> bool:
322+
if not rollout.runtime_evaluation_rule:
323+
return self._is_runtime_evaluation_satisfied(rollout, context)
324+
if not (custom_properties := context.get("custom_properties")):
325+
return False
326+
if not isinstance(custom_properties, dict):
327+
return False
328+
import json_logic
329+
try:
330+
result = json_logic.jsonLogic(rollout.runtime_evaluation_rule, custom_properties)
331+
return bool(result)
332+
except Exception as e:
333+
logger.exception("Error evaluating runtime evaluation rule", e)
334+
return False
320335

321336
def _is_runtime_evaluation_satisfied(
322337
self, rollout: Rollout, context: Dict[str, Any]

‎mixpanel/flags/test_local_feature_flags.py‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ async def test_get_variant_value_returns_variant_when_rollout_percentage_hundred
189189
# TODO problem test doesn't fail
190190
@respx.mock
191191
async def test_get_variant_value_respects_runtime_evaluation_rule_satisfied(self):
192-
runtime_eval = {"oops": "sorry"}
192+
runtime_eval = {
193+
"==": [{"var": "plan"}, "premium"]
194+
}
193195
flag = create_test_flag(runtime_evaluation_rule=runtime_eval)
194196
await self.setup_flags([flag])
195197
context = {
@@ -204,7 +206,9 @@ async def test_get_variant_value_respects_runtime_evaluation_rule_satisfied(self
204206

205207
@respx.mock
206208
async def test_get_variant_value_respects_runtime_evaluation_rule_not_satisfied(self):
207-
runtime_eval = {"oops": "sorry"}
209+
runtime_eval = {
210+
"==": [{"var": "plan"}, "basic"]
211+
}
208212
flag = create_test_flag(runtime_evaluation_rule=runtime_eval)
209213
await self.setup_flags([flag])
210214
context = {

‎mixpanel/flags/types.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class VariantOverride(BaseModel):
3131
class Rollout(BaseModel):
3232
rollout_percentage: float
3333
runtime_evaluation_definition: Optional[Dict[str, str]] = None
34-
runtime_evaluation_rule: Optional[Dict[str, str]] = None
34+
runtime_evaluation_rule: Optional[Dict[Any, Any]] = None
3535
variant_override: Optional[VariantOverride] = None
3636
variant_splits: Optional[Dict[str,float]] = None
3737

0 commit comments

Comments
 (0)