Rules engine
Project description
Getting Started
Description
Simple rules engine inspired by Martin Fowler's blog post in 2009 and funnel-rules-engine.
Full Documentation can be found here
Requirements
python >= 3.6
How to install
pip install rules-engine
How to use
from rules_engine import Rule, RulesEngine, when, then
name = "fyndiq"
RulesEngine(Rule(when(name == "fyndiq"),then(True))).run(name)
>>> True
When
Evaluates a condition.
let's check if a value is None
and raise an exception.
from rules_engine import Rule, RulesEngine, when
obj = None
def cannot_be_none_error():
return "not a string error"
RulesEngine(Rule(when(obj is None), cannot_be_none_error)).run(obj)
>>> 'not a string error'
Then
Evaluates an action.
from rules_engine import Rule, RulesEngine, when
obj = None
RulesEngine(Rule(when(obj is None), then('not a string error'))).run(obj)
>>> 'not a string error'
Not
The not_
keyword is a logical operator.
The return value will be True
if the statement(s) are not True
, otherwise it will return False
.
from rules_engine import Rule, RulesEngine, not_
def is_missing(obj):
return not obj
obj="Hello"
RulesEngine(Rule(not_(is_missing), then(True))).run(obj)
>>> True
All
Evaluates multiple conditions and if all conditions are True
the action is executed
- Example:
- We need to check if an object
obj
is not missing and is of typelist
- We need to check if an object
from rules_engine import Rule, RulesEngine, all_
def is_missing(obj):
return not obj
def is_a_list(obj):
return isinstance(obj, list)
obj = [1,2]
RulesEngine(Rule(all_(not_(is_missing), is_a_list), then(True))).run(obj)
>>> True
Any
Evaluates multiple conditions and if any of the conditions is True
the action is executed
- Example:
- We need to check if an object
obj
is astr
or alist
- We need to check if an object
from rules_engine import Rule, RulesEngine, any_
def is_a_str(obj):
return isinstance(obj, str)
def is_a_list(obj):
return isinstance(obj, list)
obj = "Hello"
RulesEngine(Rule(any_(is_a_str, is_a_list), then(True))).run(obj)
>>> True
Run/RunAll
Run
Runs rules sequentially and exists executes the action for the first passing condition.
from rules_engine import Rule, RulesEngine, then
obj = None
def is_integer(value):
return isinstance(value, int)
def is_string(value):
return isinstance(value, str)
value=1234
RulesEngine(
Rule(is_integer, then("integer")),
Rule(is_string, then("string")),
).run(value)
>>> "integer"
Since the first rule satisfies the conditions the rules engine will go no further
RunAll
Evaluates all conditions and adds them to a list
from rules_engine import Rule, RulesEngine, then
def is_integer(value):
return isinstance(value, int)
def is_string(value):
return isinstance(value, str)
def is_gr_3_chars(value):
return len(value) > 3
value="Hello"
RulesEngine(
Rule(is_integer, then("integer")),
Rule(is_string, then("string")),
Rule(is_gr_3_chars, then("greater than 3 charcters")),
).run_all(value)
>>> ["string", "greater than 3 charcters"]
Full Example
In order for an article to be completed it must have the following rules
- stock is > 0.
- image url is present.
- price exists.
from collections import namedtuple
from typing import Union
from rules_engine import Otherwise, Rule, RulesEngine, then
Article = namedtuple("Article", "title price image_url stock")
article = Article(title="Iphone Case", price=1000, image_url="http://localhost/image", stock=None)
def produce_article_completed_event():
return None
def article_controller(article: Article):
if not article.stock:
return False
if not article.price:
raise ValueError("Article price missing")
if not article.image_url:
raise ValueError("Article image_url missing")
return produce_article_completed_event()
To be able to change to rules engine, we need to split the conditions and actions.
Rules engine is pretty simple if the condition is True
, its corresponding action will be executed.
### Conditions
def no_article_stock(article):
return not article.stock
def no_article_price(article):
return not article.price
def no_article_image_url(article):
return not article.image_url
### Actions
def article_price_missing_error(article):
raise ValueError("Article price missing")
def article_image_missing_error(article):
raise ValueError("Article image_url missing")
### Rules Engine
def article_complete_rules(article):
RulesEngine(
Rule(no_article_stock, then(False)),
Rule(no_article_price, article_price_missing_error),
Rule(no_article_image_url, article_image_missing_error),
Otherwise(produce_article_completed_event()),
).run(article)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file rules-engine-0.3.0.tar.gz
.
File metadata
- Download URL: rules-engine-0.3.0.tar.gz
- Upload date:
- Size: 5.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.0 CPython/3.10.9
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 75eda6f559c3fbd6e6dca06b9fd4329986b197d09a6bbd4f6e87c110fed61624 |
|
MD5 | 99455e4f1a77d5f24882a606d896c1de |
|
BLAKE2b-256 | ac67d6ff269edd27691be215ec052e526d7dacaa6b793158d930280a0b59f2b9 |
File details
Details for the file rules_engine-0.3.0-py3-none-any.whl
.
File metadata
- Download URL: rules_engine-0.3.0-py3-none-any.whl
- Upload date:
- Size: 4.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.0 CPython/3.10.9
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6e7f7326187804b1c7eb8b89f548fb23949ee0dde5a940f1090f82d746d82e69 |
|
MD5 | 1ada8adf4535b6de0f08947ddbf1adca |
|
BLAKE2b-256 | 9b501ca856f717f3c10c0f893289766272d8eefd875bc76a97ab47b483fbd314 |