|
16 | 16 | from arta.config import load_config
|
17 | 17 | from arta.models import Configuration, RulesDict
|
18 | 18 | from arta.rule import Rule
|
19 |
| -from arta.utils import ParsingErrorStrategy |
| 19 | +from arta.utils import ParsingErrorStrategy, RuleActivationMode |
20 | 20 |
|
21 | 21 |
|
22 | 22 | class RulesEngine:
|
@@ -81,8 +81,10 @@ def __init__(
|
81 | 81 | "RulesEngine takes one (and only one) parameter: 'rules_dict' or 'config_path' or 'config_dict'."
|
82 | 82 | )
|
83 | 83 |
|
84 |
| - # Init. default parsing_error_strategy (probably not needed because already defined elsewhere) |
| 84 | + # Init. default global settings (useful if not set, can't be set in the Pydantic model |
| 85 | + # because of the rules dict mode) |
85 | 86 | self._parsing_error_strategy: ParsingErrorStrategy = ParsingErrorStrategy.RAISE
|
| 87 | + self._rule_activation_mode: RuleActivationMode = RuleActivationMode.ONE_BY_GROUP |
86 | 88 |
|
87 | 89 | # Initialize directly with a rules dict
|
88 | 90 | if rules_dict is not None:
|
@@ -112,6 +114,10 @@ def __init__(
|
112 | 114 | # Set parsing error handling strategy from config
|
113 | 115 | self._parsing_error_strategy = ParsingErrorStrategy(config.parsing_error_strategy)
|
114 | 116 |
|
| 117 | + if config.rule_activation_mode is not None: |
| 118 | + # Set rule activation mode from config |
| 119 | + self._rule_activation_mode = RuleActivationMode(config.rule_activation_mode) |
| 120 | + |
115 | 121 | # dict of available action functions (k: function name, v: function object)
|
116 | 122 | action_modules: list[str] = config.actions_source_modules
|
117 | 123 | action_functions: dict[str, Callable] = self._get_object_from_source_modules(action_modules)
|
@@ -166,7 +172,8 @@ def apply_rules(
|
166 | 172 | """Apply the rules and return results.
|
167 | 173 |
|
168 | 174 | For each rule group of a given rule set, rules are applied sequentially,
|
169 |
| - The loop is broken when a rule is applied (an action is triggered). |
| 175 | + The loop is broken when a rule is applied (an action is triggered) |
| 176 | + or not (depends on the rule activation mode). |
170 | 177 | Then, the next rule group is evaluated.
|
171 | 178 | And so on...
|
172 | 179 |
|
@@ -241,8 +248,9 @@ def apply_rules(
|
241 | 248 | # Update input data with current result with key 'output' (can be used in next rules)
|
242 | 249 | input_data_copy["output"][group_id] = copy.deepcopy(results_dict[group_id])
|
243 | 250 |
|
244 |
| - # We can only have one result per group => break when "action_result" in rule_details |
245 |
| - break |
| 251 | + if self._rule_activation_mode is RuleActivationMode.ONE_BY_GROUP: |
| 252 | + # We can only have one result per group => break when "action_result" in rule_details |
| 253 | + break |
246 | 254 |
|
247 | 255 | # Handling non-verbose mode
|
248 | 256 | if not verbose:
|
|
0 commit comments