def newRule(request): url = reverse('new-rule') data = json.dumps(export_rule_data(ProductVariables, ProductActions)) if request.method == 'POST': form = RuleForm(request.POST) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('rule-list')) else: form = RuleForm() return render(request, 'newRule.html', { 'form': form, 'data': data, 'url': url })
def editRule(request, ruleId): url = reverse('edit-rule', args=[ruleId]) data = json.dumps(export_rule_data(ProductVariables, ProductActions)) rule = get_object_or_404(Rule, pk=ruleId) if request.method == 'POST': form = RuleForm(request.POST, instance=rule) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('rule-list')) else: form = RuleForm(instance=rule) return render(request, 'newRule.html', { 'form': form, 'data': data, 'url': url })
def process_rules(custom_rule_file, descriptor_file_name): # def process_rules(custom_rule_file): # Read YAML rule file if not os.path.isfile(custom_rule_file): log.error("Invalid custom rule file") exit(1) try: fn_custom_rule = open(custom_rule_file, "r") except IOError: log.error("Error opening custom rule file: " "File does not appear to exist.") exit(1) try: rules = yaml.load(fn_custom_rule) except (yaml.YAMLError, yaml.MarkedYAMLError) as e: log.error("The rule file seems to have contain invalid YAML syntax." " Please fix and try again. Error: {}".format(str(e))) exit(1) storage = DescriptorStorage() # descriptor_source = read_descriptor_file(descriptor_file_name) func = storage.create_function(descriptor_file_name) if not func: evtlog.log( "Invalid function descriptor, Couldn't store " "VNF of file '{0}'".format(descriptor_file_name), descriptor_file_name, 'evt_function_invalid_descriptor') exit(1) # TODO populate descriptor from file # descriptor= Descriptor(func,"cona",1000,5,5,1) descriptor = Descriptor(func) variables = DescriptorVariables(descriptor) rule_to_export = export_rule_data(DescriptorVariables, DescriptorActions) # print("DUMP OF RULES: \n"+json.dumps(rules)) # Execute all the rules triggered = run_all(rule_list=rules, defined_variables=DescriptorVariables(descriptor), defined_actions=DescriptorActions(descriptor), stop_on_first_trigger=False) return descriptor.errors
def get_variables(): logger.info('ENTER get_variables()') try: rule_data = export_rule_data(MediainfoVariables, MediainfoActions) logger.info("{}".format(json.dumps(rule_data, indent=4, sort_keys=True))) except Exception as e: logger.info("Error getting rule data {}".format(e)) raise ChaliceViewError("Dynamodb returned error message '%s'" % e) logger.info('LEAVE get_variables: {}'.format( json.dumps(rule_data, indent=4, sort_keys=True))) return rule_data
from business_rules import export_rule_data from models import * import json import os json_data = export_rule_data(SongVariables, SongActions) mode = 'r+' if os.path.exists('model.json') else 'w' with open('model.json', mode) as a_file: if mode == 'r+': a_file.read() a_file.seek(0) json.dump(json_data, a_file) a_file.truncate()
def test_export_rule_data(self): """ Tests that export_rule_data has the three expected keys in the right format. """ all_data = export_rule_data(SomeVariables(), SomeActions()) self.assertEqual(all_data.get("actions"), [{"name": "some_action", "label": "Some Action", "params": [{'fieldType': 'numeric', 'label': 'Foo', 'name': 'foo'}]}, {"name": "some_other_action", "label": "woohoo", "params": [{'fieldType': 'text', 'label': 'Bar', 'name': 'bar'}]}, {"name": "some_select_action", "label": "Some Select Action", "params":[{'fieldType': FIELD_SELECT, 'name': 'baz', 'label': 'Baz', 'options': [ {'label': 'Chose Me', 'name': 'chose_me'}, {'label': 'Or Me', 'name': 'or_me'} ]}] } ]) self.assertEqual(all_data.get("variables"), [{"name": "foo", "label": "Foo", "field_type": "string", "options": []}, {"name": "ten", "label": "Diez", "field_type": "numeric", "options": []}, {'name': 'true_bool', 'label': 'True Bool', 'field_type': 'boolean', 'options': []}]) print all_data.get("variable_type_operators") self.assertEqual(all_data.get("variable_type_operators"), { 'select_multiple': [{ 'input_type': 'select_multiple', 'name': 'contains_all', 'label': 'Contains All' }, { 'input_type': 'select_multiple', 'name': 'is_contained_by', 'label': 'Is Contained By' }, { 'input_type': 'select_multiple', 'name': 'shares_at_least_one_element_with', 'label': 'Shares At Least One Element With' }, { 'input_type': 'select_multiple', 'name': 'shares_exactly_one_element_with', 'label': 'Shares Exactly One Element With' }, { 'input_type': 'select_multiple', 'name': 'shares_no_elements_with', 'label': 'Shares No Elements With' }], 'string': [{ 'input_type': 'text', 'name': 'contains', 'label': 'Contains' }, { 'input_type': 'text', 'name': 'ends_with', 'label': 'Ends With' }, { 'input_type': 'text', 'name': 'equal_to', 'label': 'Equal To' }, { 'input_type': 'text', 'name': 'equal_to_case_insensitive', 'label': 'Equal To (case insensitive)' }, { 'input_type': 'text', 'name': 'matches_regex', 'label': 'Matches Regex' }, { 'input_type': 'none', 'name': 'non_empty', 'label': 'Non Empty' }, { 'input_type': 'text', 'name': 'starts_with', 'label': 'Starts With' }], 'numeric': [{ 'input_type': 'numeric', 'name': 'equal_to', 'label': 'Equal To' }, { 'input_type': 'numeric', 'name': 'greater_than', 'label': 'Greater Than' }, { 'input_type': 'numeric', 'name': 'greater_than_or_equal_to', 'label': 'Greater Than Or Equal To' }, { 'input_type': 'numeric', 'name': 'less_than', 'label': 'Less Than' }, { 'input_type': 'numeric', 'name': 'less_than_or_equal_to', 'label': 'Less Than Or Equal To' }], 'boolean': [{ 'input_type': 'none', 'name': 'is_false', 'label': 'Is False' }, { 'input_type': 'none', 'name': 'is_true', 'label': 'Is True' }], 'custom_operator': [], 'select': [{ 'input_type': 'select', 'name': 'contains', 'label': 'Contains' }, { 'input_type': 'select', 'name': 'does_not_contain', 'label': 'Does Not Contain' }] })
def test_export_rule_data(self): """ Tests that export_rule_data has the three expected keys in the right format. """ all_data = export_rule_data(SomeVariables(), SomeActions()) self.assertEqual(all_data.get("actions"), [ { "name": "some_action", "label": "Some Action", "params": [{ 'fieldType': 'numeric', 'label': 'Foo', 'name': 'foo' }] }, { "name": "some_other_action", "label": "woohoo", "params": [{ 'fieldType': 'text', 'label': 'Bar', 'name': 'bar' }] }, { "name": "some_select_action", "label": "Some Select Action", "params": [{ 'fieldType': FIELD_SELECT, 'name': 'baz', 'label': 'Baz', 'options': [{ 'label': 'Chose Me', 'name': 'chose_me' }, { 'label': 'Or Me', 'name': 'or_me' }] }] } ]) self.assertEqual(all_data.get("variables"), [{ "name": "foo", "label": "Foo", "field_type": "string", "options": [] }, { 'field_type': 'numeric', 'label': 'Returns Tuple', 'name': 'returns_tuple', 'options': [] }, { 'field_type': 'numeric', 'label': 'Series Of Values Indexed By Minute', 'name': 'series_of_values_indexed_by_minute', 'options': [] }, { "name": "ten", "label": "Diez", "field_type": "numeric", "options": [] }, { 'name': 'true_bool', 'label': 'True Bool', 'field_type': 'boolean', 'options': [] }]) self.assertEqual( all_data.get("variable_type_operators"), { 'boolean': [{ 'input_type': 'none', 'label': 'Is False', 'name': 'is_false' }, { 'input_type': 'none', 'label': 'Is True', 'name': 'is_true' }], 'numeric': [{ 'name': 'difference_greater_than', 'label': 'Difference Greater Than', 'input_type': 'numeric' }, { 'name': 'difference_greater_than_percent', 'label': 'Difference Greater Than Percent', 'input_type': 'numeric' }, { 'name': 'difference_less_than', 'label': 'Difference Less Than', 'input_type': 'numeric' }, { 'name': 'difference_less_than_percent', 'label': 'Difference Less Than Percent', 'input_type': 'numeric' }, { 'input_type': 'numeric', 'label': 'Equal To', 'name': 'equal_to' }, { 'input_type': 'numeric', 'label': 'Greater Than', 'name': 'greater_than' }, { 'input_type': 'numeric', 'label': 'Greater Than Or Equal To', 'name': 'greater_than_or_equal_to' }, { 'input_type': 'numeric', 'label': 'Less Than', 'name': 'less_than' }, { 'input_type': 'numeric', 'label': 'Less Than Or Equal To', 'name': 'less_than_or_equal_to' }], 'select': [{ 'input_type': 'select', 'label': 'Contains', 'name': 'contains' }, { 'input_type': 'select', 'label': 'Does Not Contain', 'name': 'does_not_contain' }], 'select_multiple': [{ 'input_type': 'select_multiple', 'label': 'Contains All', 'name': 'contains_all' }, { 'input_type': 'select_multiple', 'label': 'Is Contained By', 'name': 'is_contained_by' }, { 'input_type': 'select_multiple', 'label': 'Shares At Least One Element With', 'name': 'shares_at_least_one_element_with' }, { 'input_type': 'select_multiple', 'label': 'Shares Exactly One Element With', 'name': 'shares_exactly_one_element_with' }, { 'input_type': 'select_multiple', 'label': 'Shares No Elements With', 'name': 'shares_no_elements_with' }], 'string': [{ 'input_type': 'text', 'label': 'Contains', 'name': 'contains' }, { 'input_type': 'text', 'label': 'Ends With', 'name': 'ends_with' }, { 'input_type': 'text', 'label': 'Equal To', 'name': 'equal_to' }, { 'input_type': 'text', 'label': 'Equal To (case insensitive)', 'name': 'equal_to_case_insensitive' }, { 'input_type': 'text', 'label': 'Matches Regex', 'name': 'matches_regex' }, { 'input_type': 'none', 'label': 'Non Empty', 'name': 'non_empty' }, { 'input_type': 'text', 'label': 'Not Equal To', 'name': 'not_equal_to' }, { 'input_type': 'text', 'label': 'Starts With', 'name': 'starts_with' }] })
from business_rules import export_rule_data,run_all from WeatherVariables import WeatherVariables from AgriActions import AgriActions export_rule_data(WeatherVariables,AgriActions) rules = [ { "conditions": { "all": [ { "name": "rainfall_total", "operator": "greater_than_or_equal_to", "value": 30, } ]}, "actions": [ { "name": "high_rain" }, ], }, {"conditions": {"all": [ { "name": "rainfall_total", "operator": "less_than", "value": 30, }, { "name": "rainfall_total", "operator": "greater_than", "value": 0, } ]}, "actions": [ {"name": "low_rain"},
def test_1(): # rules = _some_function_to_receive_from_client() rules = """ [{ "conditions": { "all": [{ "name": "expiration_days", "operator": "less_than", "value": 5 }, { "name": "current_inventory", "operator": "greater_than", "value": 20 } ] }, "actions": [{ "name": "put_on_sale", "params": { "sale_percentage": 0.25 } }] }, { "conditions": { "any": [{ "name": "current_inventory", "operator": "less_than", "value": 5 }] }, "actions": [{ "name": "order_more", "params": { "number_to_order": 40 } }] } ]""" class Order: def __init__(self): self.expiration_date = datetime.datetime.now().date() class Product: """ Product to test rules """ def __init__(self): self.id = 1 self.price = 1.34 self.current_inventory = 21 self.orders = [Order(), Order()] class ProductVariables(BaseVariables): def __init__(self, product): self.product = product @numeric_rule_variable def current_inventory(self): return self.product.current_inventory @numeric_rule_variable(label='Days until expiration') def expiration_days(self): last_order = self.product.orders[-1] return (last_order.expiration_date - datetime.date.today()).days @string_rule_variable() def current_month(self): return datetime.datetime.now().strftime("%B") class ProductActions(BaseActions): def __init__(self, product): self.product = product @rule_action(params={"sale_percentage": FIELD_NUMERIC}) def put_on_sale(self, sale_percentage): # self.product.price = (1.0 - sale_percentage) * self.product.price # self.product.save() return (1.0 - sale_percentage) * self.product.price @rule_action(params={"number_to_order": FIELD_NUMERIC}) def order_more(self, number_to_order): # Product(product_id=self.product.id, # quantity=number_to_order) return number_to_order export_result = export_rule_data(ProductVariables, ProductActions) rules = json.loads(rules) product = Product() # actions = ProductActions(product) # vars = ProductVariables(product) run_all_result = run(rule_list=rules, defined_variables=ProductVariables(product), defined_actions=ProductActions(product), stop_on_first_trigger=False) print(run_all_result) assert run_all_result is not None
@numeric_rule_variable def maximum_amount_owed(self): return self.credit.maximum_amount_owed class CreditActions(BaseActions): def __init__(self, credit): self.credit = credit @rule_action(params={'score_positive': FIELD_NUMERIC}) def current_balance_less(self, score_positive): print("current_balance_less previus score_positive" + str(self.credit.initial_score)) self.credit.initial_score += score_positive print("current_balance_less previus score_positive" + str(self.credit.initial_score)) with open("rules.json") as data_file: rules = json.loads(data_file.read()) listOfCredits = [Credit(120120, 1020, datetime.datetime.now(), 2120210)] for product in listOfCredits: rule_was_triggered = run_all(rule_list=rules, defined_variables=CreditVariables(product), defined_actions=CreditActions(product), stop_on_first_trigger=True) json = export_rule_data(CreditVariables, CreditActions) print(json)
def test_export_rule_data(self): """ Tests that export_rule_data has the three expected keys in the right format. """ all_data = export_rule_data(SomeVariables(), SomeActions()) self.assertListEqual(all_data.get("actions"), [ { 'name': 'some_action', 'label': 'Some Action', 'params': [{ 'label': 'Foo', 'name': 'foo', 'fieldType': 'numeric' }], 'tooltip': '' }, { 'name': 'some_other_action', 'label': 'woohoo', 'params': [{ 'label': 'Bar', 'name': 'bar', 'fieldType': 'text' }], 'tooltip': 'A nice docstring for you!' }, { 'name': 'some_select_action', 'label': 'Some Select Action', 'params': [{ 'fieldType': 'select', 'name': 'baz', 'label': 'Baz', 'options': [{ 'label': 'Chose Me', 'name': 'chose_me' }, { 'label': 'Or Me', 'name': 'or_me' }] }], 'tooltip': '' } ]) self.assertListEqual(all_data.get("variables"), [{ 'name': 'foo', 'label': 'Foo', 'field_type': 'string', 'options': [], 'params': {}, 'tooltip': '' }, { 'name': 'foo_bar', 'label': 'Foo Bar', 'field_type': 'string', 'options': [], 'params': { 'foo': 'text', 'bar': 'text' }, 'tooltip': 'Foobar' }, { 'name': 'ten', 'label': 'FooBar', 'field_type': 'numeric', 'options': [], 'params': { 'foo_bar': 'numeric' }, 'tooltip': '' }, { 'name': 'true_bool', 'label': 'True Bool', 'field_type': 'boolean', 'options': [], 'params': {}, 'tooltip': '' }]) self.assertDictEqual( all_data.get("variable_type_operators"), { 'boolean': [{ 'name': 'is_false', 'label': 'Is False', 'input_type': 'none' }, { 'name': 'is_true', 'label': 'Is True', 'input_type': 'none' }], 'date': [{ 'name': 'equal_to', 'label': 'Equal To', 'input_type': 'date' }, { 'name': 'greater_than', 'label': 'Greater Than', 'input_type': 'date' }, { 'name': 'greater_than_or_equal_to', 'label': 'Greater Than Or Equal To', 'input_type': 'date' }, { 'name': 'less_than', 'label': 'Less Than', 'input_type': 'date' }, { 'name': 'less_than_or_equal_to', 'label': 'Less Than Or Equal To', 'input_type': 'date' }, { 'name': 'not_equal_to', 'label': 'Not Equal To', 'input_type': 'date' }], 'numeric': [{ 'name': 'equal_to', 'label': 'Equal To', 'input_type': 'numeric' }, { 'name': 'greater_than', 'label': 'Greater Than', 'input_type': 'numeric' }, { 'name': 'greater_than_or_equal_to', 'label': 'Greater Than Or Equal To', 'input_type': 'numeric' }, { 'name': 'less_than', 'label': 'Less Than', 'input_type': 'numeric' }, { 'name': 'less_than_or_equal_to', 'label': 'Less Than Or Equal To', 'input_type': 'numeric' }, { 'name': 'not_equal_to', 'label': 'Not Equal To', 'input_type': 'numeric' }], 'select_multiple': [{ 'name': 'contains_all', 'label': 'Contains All', 'input_type': 'select_multiple' }, { 'name': 'is_contained_by', 'label': 'Is Contained By', 'input_type': 'select_multiple' }, { 'name': 'is_not_contained_by', 'label': 'Is Not Contained By', 'input_type': 'select_multiple' }, { 'name': 'shares_at_least_one_element_with', 'label': 'Shares At Least One Element With', 'input_type': 'select_multiple' }, { 'name': 'shares_exactly_one_element_with', 'label': 'Shares Exactly One Element With', 'input_type': 'select_multiple' }, { 'name': 'shares_no_elements_with', 'label': 'Shares No Elements With', 'input_type': 'select_multiple' }], 'select': [{ 'name': 'contains', 'label': 'Contains', 'input_type': 'select' }, { 'name': 'does_not_contain', 'label': 'Does Not Contain', 'input_type': 'select' }], 'string': [{ 'name': 'contains', 'label': 'Contains', 'input_type': 'text' }, { 'name': 'ends_with', 'label': 'Ends With', 'input_type': 'text' }, { 'name': 'equal_to', 'label': 'Equal To', 'input_type': 'text' }, { 'name': 'equal_to_case_insensitive', 'label': 'Equal To (case insensitive)', 'input_type': 'text' }, { 'name': 'matches_regex', 'label': 'Matches Regex', 'input_type': 'text' }, { 'name': 'non_empty', 'label': 'Non Empty', 'input_type': 'none' }, { 'name': 'not_equal_to', 'label': 'Not Equal To', 'input_type': 'text' }, { 'name': 'starts_with', 'label': 'Starts With', 'input_type': 'text' }] })
def test_export_rule_data(self): """ Tests that export_rule_data has the three expected keys in the right format. """ all_data = export_rule_data(SomeVariables(), SomeActions()) self.assertEqual(all_data.get("actions"), [ { "name": "some_action", "label": "Some Action", "params": [{ 'fieldType': 'numeric', 'label': 'Foo', 'name': 'foo' }] }, { "name": "some_other_action", "label": "woohoo", "params": [{ 'fieldType': 'text', 'label': 'Bar', 'name': 'bar' }] }, { "name": "some_select_action", "label": "Some Select Action", "params": [{ 'fieldType': FIELD_SELECT, 'name': 'baz', 'label': 'Baz', 'options': [{ 'label': 'Chose Me', 'name': 'chose_me' }, { 'label': 'Or Me', 'name': 'or_me' }] }] } ]) self.assertEqual(all_data.get("variables"), [{ "name": "foo", "label": "Foo", "field_type": "string", "options": [] }, { "name": "ten", "label": "Diez", "field_type": "numeric", "options": [] }, { 'name': 'true_bool', 'label': 'True Bool', 'field_type': 'boolean', 'options': [] }]) """