1
1
import logging
2
- from typing import Any , Dict , List , Optional , Union , cast
2
+ from typing import Any , Callable , Dict , List , Optional , Union , cast
3
3
4
4
from . import schema
5
5
from .base import StoreProvider
9
9
10
10
11
11
class FeatureFlags :
12
- def __init__ (self , store : StoreProvider ):
12
+ def __init__ (self , store : StoreProvider , user_mapping_by_action : Optional [ Dict [ str , Callable ]] = None ):
13
13
"""Evaluates whether feature flags should be enabled based on a given context.
14
14
15
15
It uses the provided store to fetch feature flag rules before evaluating them.
@@ -35,20 +35,32 @@ def __init__(self, store: StoreProvider):
35
35
----------
36
36
store: StoreProvider
37
37
Store to use to fetch feature flag schema configuration.
38
+ user_mapping_by_action: Dict[str, Callable]
39
+ User mapping of actions to a callable (context_value, condition_value)
38
40
"""
39
41
self ._store = store
42
+ self ._user_mapping_by_action = user_mapping_by_action
40
43
41
44
@staticmethod
42
- def _match_by_action (action : str , condition_value : Any , context_value : Any ) -> bool :
45
+ def _match_by_action (
46
+ action : str ,
47
+ condition_value : Any ,
48
+ context_value : Any ,
49
+ user_mapping_by_action : Optional [Dict [str , Callable ]] = None ,
50
+ ) -> bool :
43
51
if not context_value :
44
52
return False
45
- mapping_by_action = {
53
+ _mapping_by_action = {
46
54
schema .RuleAction .EQUALS .value : lambda a , b : a == b ,
47
55
schema .RuleAction .STARTSWITH .value : lambda a , b : a .startswith (b ),
48
56
schema .RuleAction .ENDSWITH .value : lambda a , b : a .endswith (b ),
49
57
schema .RuleAction .IN .value : lambda a , b : a in b ,
50
58
schema .RuleAction .NOT_IN .value : lambda a , b : a not in b ,
51
59
}
60
+ mapping_by_action = {}
61
+ if user_mapping_by_action :
62
+ mapping_by_action .update (user_mapping_by_action )
63
+ mapping_by_action .update (_mapping_by_action )
52
64
53
65
try :
54
66
func = mapping_by_action .get (action , lambda a , b : False )
@@ -76,7 +88,12 @@ def _evaluate_conditions(
76
88
cond_action = condition .get (schema .CONDITION_ACTION , "" )
77
89
cond_value = condition .get (schema .CONDITION_VALUE )
78
90
79
- if not self ._match_by_action (action = cond_action , condition_value = cond_value , context_value = context_value ):
91
+ if not self ._match_by_action (
92
+ action = cond_action ,
93
+ condition_value = cond_value ,
94
+ context_value = context_value ,
95
+ user_mapping_by_action = self ._user_mapping_by_action ,
96
+ ):
80
97
logger .debug (
81
98
f"rule did not match action, rule_name={ rule_name } , rule_value={ rule_match_value } , "
82
99
f"name={ feature_name } , context_value={ str (context_value )} "
0 commit comments