{"id":14480,"library":"business-rules","title":"Business Rules","description":"Business Rules is a Python Domain Specific Language (DSL) that allows you to define business intelligence rules without writing direct code. It provides a framework for defining 'variables' (data points) and 'actions' (operations) and then executing JSON-defined rules against them. The current stable version is 1.1.1, with releases occurring infrequently for maintenance and compatibility updates.","status":"active","version":"1.1.1","language":"en","source_language":"en","source_url":"https://github.com/venmo/business-rules","tags":["rules-engine","business-logic","dsl","workflow"],"install":[{"cmd":"pip install business-rules","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"Pre-1.0 versions used BaseRules for both variables and actions; post-1.0 uses separate BaseVariables and BaseActions.","wrong":"from business_rules.rules import BaseRules","symbol":"BaseVariables","correct":"from business_rules.variables import BaseVariables"},{"symbol":"rule_variable","correct":"from business_rules.variables import rule_variable"},{"symbol":"BaseActions","correct":"from business_rules.actions import BaseActions"},{"symbol":"rule_action","correct":"from business_rules.actions import rule_action"},{"symbol":"FIELD_NUMERIC","correct":"from business_rules.fields import FIELD_NUMERIC"},{"note":"The rule_set function and BaseRules.run() were deprecated/removed in favor of run_all in versions 1.0+","wrong":"from business_rules.core import rule_set","symbol":"run_all","correct":"from business_rules.run_all import run_all"}],"quickstart":{"code":"from business_rules.actions import BaseActions, rule_action\nfrom business_rules.fields import FIELD_NUMERIC, FIELD_TEXT\nfrom business_rules.variables import BaseVariables, rule_variable\nfrom business_rules.run_all import run_all\n\n# 1. Define your data source (variables)\nclass SomeVariables(BaseVariables):\n\n    def __init__(self, some_object):\n        self.some_object = some_object\n\n    @rule_variable(FIELD_NUMERIC)\n    def some_numeric_variable(self):\n        return self.some_object.some_numeric_value\n\n    @rule_variable(FIELD_TEXT)\n    def some_text_variable(self):\n        return self.some_object.some_text_value\n\n# 2. Define actions to take when rules are met\nclass SomeActions(BaseActions):\n\n    def __init__(self, some_object):\n        self.some_object = some_object\n\n    @rule_action(params=[{'fieldType': FIELD_NUMERIC, 'name': 'some_param'}])\n    def some_action(self, some_param):\n        self.some_object.some_action_has_run = True\n        self.some_object.some_action_param = some_param\n\n# Example object to apply rules to\nclass MyDataObject:\n    some_numeric_value = 15\n    some_text_value = \"hello world\"\n    some_action_has_run = False\n    some_action_param = None\n\nmy_data_object = MyDataObject()\n\n# 3. Define your rules in a JSON-like structure\nrules = [{\n    \"conditions\": {\n        \"all\": [\n            {\n                \"name\": \"some_numeric_variable\",\n                \"operator\": \"greater_than\",\n                \"value\": 10\n            },\n            {\n                \"name\": \"some_text_variable\",\n                \"operator\": \"contains\",\n                \"value\": \"hello\"\n            }\n        ]\n    },\n    \"actions\": [\n        {\n            \"name\": \"some_action\",\n            \"params\": {\"some_param\": 123}\n        }\n    ]\n}]\n\n# 4. Run the rules\nrun_all(\n    rules=rules,\n    defined_variables=SomeVariables(my_data_object),\n    defined_actions=SomeActions(my_data_object),\n    stop_on_first_failure=False\n)\n\nprint(f\"Action has run: {my_data_object.some_action_has_run}\")\nprint(f\"Action parameter: {my_data_object.some_action_param}\")","lang":"python","description":"This quickstart demonstrates how to define variables that retrieve data from an object, define actions that modify the object, and then execute a set of rules (defined in a JSON-like dictionary) against that object using `run_all`. The rules check if a numeric variable is greater than 10 AND if a text variable contains 'hello'. If both conditions are true, a specified action is triggered."},"warnings":[{"fix":"Migrate `BaseRules` implementations to `BaseVariables` and `BaseActions` classes. Replace `BaseRules.run()` or `rule_set()` calls with `run_all()`.","message":"Major API changes occurred in version 1.0 (August 2017), primarily refactoring `BaseRules` into `BaseVariables` and `BaseActions`, and introducing `run_all` as the main execution entry point. Code written for pre-1.0 versions will break.","severity":"breaking","affected_versions":"<1.0"},{"fix":"No fix needed for the library itself; it runs on modern Python 3. If you encounter installation issues due to environment, consider manually specifying a Python 3 environment.","message":"The `requires_python` metadata on PyPI for `business-rules` (e.g., `>=2.7, !=3.0.*, ... !=3.4.*`) is outdated and misleading. The library is fully compatible with Python 3.5+ up to at least 3.9 (and likely newer), as confirmed by release notes and PyPI classifiers. Don't be deterred by the old `requires_python` string.","severity":"gotcha","affected_versions":"All 1.x versions"},{"fix":"Embrace the JSON definition format for rules. Consider using a JSON or YAML file for external rule storage and loading it into your application for `run_all`.","message":"Rules are defined using a JSON-like dictionary structure, not directly in Python classes/methods. This requires rules to be loaded from a JSON file, a database, or constructed as a Python dictionary. Developers expecting a purely Pythonic DSL for rule *definition* might find this unexpected.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Carefully design your rule JSON `conditions` using 'all' or 'any' as appropriate. Set `stop_on_first_failure=True` in `run_all` if you want to prevent further rule execution after an initial rule fails its conditions.","message":"Understanding the difference between 'all' and 'any' conditions in the rule JSON, and the `stop_on_first_failure` parameter in `run_all`, is crucial for correct rule evaluation logic. 'all' requires all sub-conditions to be true, 'any' requires at least one. `stop_on_first_failure` (default `False`) dictates if `run_all` stops after the first rule's conditions are not met.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure the object is correctly passed to the `defined_variables` and `defined_actions` parameters of `run_all`. Also, verify that attributes accessed within `rule_variable` and `rule_action` methods (e.g., `self.some_object.some_value`) actually exist on the object instance.","cause":"The `__init__` method of your `BaseVariables` or `BaseActions` subclass expects an object (e.g., `some_object`) but it was not correctly passed during instantiation in `run_all`, or a `rule_variable`/`rule_action` method attempts to access an attribute that doesn't exist on the provided object.","error":"AttributeError: 'SomeVariables' object has no attribute 'some_object'"},{"fix":"Refer to the `business-rules` documentation or source code for valid operators associated with each `FIELD_TYPE` (e.g., `FIELD_NUMERIC` supports `equal_to`, `greater_than`, `less_than`; `FIELD_TEXT` supports `contains`, `starts_with`, `ends_with`, etc.). Correct the operator name in your rule definition.","cause":"The rule JSON specifies an operator (e.g., `invalid_operator`) that is not recognized or is not valid for the data type of the variable it's trying to operate on (e.g., using a text-only operator like `contains` on a numeric field).","error":"No operator found for 'invalid_operator' for variable 'some_numeric_variable' of type 'numeric'."},{"fix":"Update your code to use `from business_rules.run_all import run_all` and structure your rule execution by passing `rules`, `defined_variables`, and `defined_actions` to `run_all` as shown in the quickstart example.","cause":"This error, or similar `AttributeError` messages related to `BaseRules.run()`, indicates an attempt to use an old API (`rule_set` or `BaseRules.run()`) from versions prior to 1.0. These methods have been replaced by the `run_all` function.","error":"NameError: name 'rule_set' is not defined"}],"ecosystem":"pypi"}