Created
November 19, 2014 10:28
-
-
Save onjin/2acc27efe96926d7d9e8 to your computer and use it in GitHub Desktop.
python business_rules package example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# pip install business-rules | |
from decimal import Decimal | |
from pprint import pprint | |
from business_rules import ( | |
variables, actions, fields, export_rule_data, run_all | |
) | |
class Request(object): | |
def __init__(self, contractor, cart): | |
self.contractor = contractor | |
self.cart = cart | |
class Contractor(object): | |
def __init__(self, symbol): | |
self.symbol = symbol | |
class Cart(object): | |
def __init__(self, total): | |
self.total = total | |
def get_total(self): | |
return self.total | |
class PaymentMethod(object): | |
def __init__(self, symbol, gateway_symbol, amount, is_active): | |
self.symbol = symbol | |
self.gateway_symbol = gateway_symbol | |
self.amount = amount | |
self.is_active = is_active | |
class PaymentMethodVariables(variables.BaseVariables): | |
def __init__(self, request, method): | |
self.method = method | |
self.request = request | |
@variables.string_rule_variable() | |
def current_contractor(self): | |
return getattr(self.request.contractor, 'symbol') | |
@variables.string_rule_variable() | |
def method_symbol(self): | |
return self.method.symbol | |
@variables.string_rule_variable() | |
def gateway_symbol(self): | |
return self.method.gateway.symbol | |
@variables.numeric_rule_variable() | |
def cart_total(self): | |
return self.request.cart.get_total() | |
class PaymentMethodActions(actions.BaseActions): | |
def __init__(self, request, method): | |
self.method = method | |
self.request = request | |
@actions.rule_action(params={ | |
'active': fields.FIELD_SELECT_MULTIPLE | |
}) | |
def change_active(self, active): | |
self.method.is_active = active | |
@actions.rule_action(params={ | |
'amount': fields.FIELD_NUMERIC, | |
}) | |
def set_amount(self, amount): | |
self.method.amount = amount | |
if __name__ == '__main__': | |
request = Request(Contractor('stefan'), Cart(Decimal('101'))) | |
method = PaymentMethod('cash', 'general', Decimal('1.12'), True) | |
rules = export_rule_data(PaymentMethodVariables, PaymentMethodActions) | |
pprint(rules) | |
run_all( | |
rule_list=[ | |
{ | |
'conditions': { | |
'all': [ | |
{ | |
'name': 'current_contractor', | |
'operator': 'equal_to', | |
'value': 'stefan', | |
}, | |
], | |
}, | |
'actions': [ | |
{ | |
'name': 'change_active', | |
'params': { | |
'active': False, | |
}, | |
}, | |
] | |
}, | |
{ | |
'conditions': { | |
'all': [ | |
{ | |
'name': 'cart_total', | |
'operator': 'greater_than', | |
'value': Decimal('100'), | |
}, | |
], | |
}, | |
'actions': [ | |
{ | |
'name': 'change_active', | |
'params': { | |
'active': True, | |
}, | |
}, | |
{ | |
'name': 'set_amount', | |
'params': { | |
'amount': Decimal('0'), | |
}, | |
}, | |
] | |
}, | |
], | |
defined_variables=PaymentMethodVariables(request, method), | |
defined_actions=PaymentMethodActions(request, method), | |
stop_on_first_trigger=False | |
) | |
pprint(method.__dict__) |
It should be working as
tipo_vinculaction == Asociado or (numero_salarios_minimo >= 1 and actividad_economica = Asalariado)
It's not working, look at this.
My rule list
rule_list = [
{
'actions': [{'name': 'aplica_o_no_aplica'}],
'conditions': {
'any': [
{
'name': 'tipo_vinculacion',
'operator': 'equal_to',
'value': 'Asociado',
},
],
'all': [
{
'name': 'numero_salarios_minimo',
'operator': 'greater_than_or_equal_to',
'value': 1,
},
{
'name': 'actividad_economica',
'operator': 'equal_to',
'value': 'Asalariado',
},
],
},
},
]
My main
if __name__ == '__main__':
rule3 = Rule("Asociado", "Asalariado", 1)
rules_to_evaluate = [rule3]
for rule in rules_to_evaluate:
run_all(rule_list=rule_list,
defined_variables=RuleVariables(rule),
defined_actions=RuleActions(rule),
stop_on_first_trigger=True
)
for rule in rules_to_evaluate:
print(rule)
And i get this error
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-13-0c85c2a5a640> in <module>
8 defined_variables=RuleVariables(rule),
9 defined_actions=RuleActions(rule),
---> 10 stop_on_first_trigger=True
11 )
12
c:\users\pronostica\documents\projects\bancoomeva-api\env\lib\site-packages\business_rules\engine.py in run_all(rule_list, defined_variables, defined_actions, stop_on_first_trigger)
8 rule_was_triggered = False
9 for rule in rule_list:
---> 10 result = run(rule, defined_variables, defined_actions)
11 if result:
12 rule_was_triggered = True
c:\users\pronostica\documents\projects\bancoomeva-api\env\lib\site-packages\business_rules\engine.py in run(rule, defined_variables, defined_actions)
17 def run(rule, defined_variables, defined_actions):
18 conditions, actions = rule['conditions'], rule['actions']
---> 19 rule_triggered = check_conditions_recursively(conditions, defined_variables)
20 if rule_triggered:
21 do_actions(actions, defined_actions)
c:\users\pronostica\documents\projects\bancoomeva-api\env\lib\site-packages\business_rules\engine.py in check_conditions_recursively(conditions, defined_variables)
43 # help prevent errors - any and all can only be in the condition dict
44 # if they're the only item
---> 45 assert not ('any' in keys or 'all' in keys)
46 return check_condition(conditions, defined_variables)
47
AssertionError:
I checked the documentation (https://github.com/venmo/business-rules) and they recommend to form the list of dicts like this...
# current_inventory < 5 OR (current_month = "December" AND current_inventory < 20)
{ "conditions": { "any": [
{ "name": "current_inventory",
"operator": "less_than",
"value": 5,
},
]},
{ "all": [
{ "name": "current_month",
"operator": "equal_to",
"value": "December",
},
{ "name": "current_inventory",
"operator": "less_than",
"value": 20,
}
]},
},
"actions": [
{ "name": "order_more",
"params":{"number_to_order": 40},
},
],
}]
The "all" dict is out of "conditions" key... it's not working that way neither
ou, I see now. The example in README has a syntax error, but I've found proper example in tests,
so try this one
{
"conditions": {
"any": [
{
"name": "tipo_vinculacion",
"operator": "equal_to",
"value": "Asociado",
},
{
"all": [
{
"name": "numero_salarios_minimo",
"operator": "greater_than_or_equal_to",
"value": 1,
},
{
"name": "actividad_economica",
"operator": "equal_to",
"value": "Asalariado",
},
],
},
],
},
"actions": [{"name": "aplica_o_no_aplica"}],
},
]```
ou, I see now. The example in README has a syntax error, but I've found proper example in tests,
so try this one
{ "conditions": { "any": [ { "name": "tipo_vinculacion", "operator": "equal_to", "value": "Asociado", }, { "all": [ { "name": "numero_salarios_minimo", "operator": "greater_than_or_equal_to", "value": 1, }, { "name": "actividad_economica", "operator": "equal_to", "value": "Asalariado", }, ], }, ], }, "actions": [{"name": "aplica_o_no_aplica"}], }, ]```
Ohh, finally it worked, thanks a lot!!
That's great :) you welcome.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It should be working as
tipo_vinculaction == Asociado or (numero_salarios_minimo >= 1 and actividad_economica = Asalariado)