Skip to main content

Sauron Rule engine - One engine to rule them all

Coverage Status GitHub Twitter: joaovoce

Build Status

A simple rule engine to be used in python, it is based on simple rules and actions that can be chained with each other. The idea is to run the rule processor on events and have it mutate data or trigger actions

Heavily inspired on FastAPI. We use type annotations in our engine so that we can export data to other systems or frontends to convey what conditions and actions are possible using that engine

Install

pip install sauron-rule-engine

Concepts

Sauron rule engine is based on custom functions that can be called by a rule.

Condition

Condition to be satisfied in order for the actions to run, they can take some or no parameters at all Multiple conditions can be chained in order to create more complex ones, currently all chained conditions must be satisfied

Action

An Action is the intented result. Usually they are there to mutate state or trigger/schedule other kinds of actions in your system. Actions can also be chained and will run in order.

Rule

A Rule is a dict or json string containing the conditions and actions and the arguments they should be run with. Usually those rules will be built by a frontend to match complex and adaptable business rules from your customer

Use it

A simple example of the usage

from sauron.rule_engine import RuleEngine

engine = RuleEngine()


@engine.condition("First Condition")
def first_condition(session,lower_number: int = 10, greater_number: int = 20) -> bool:
    """
    Checks if first number is lower than the first
    - lower_number: Number expected to be low
    - higher_number: Number expected to be high
    """
    return lower_number < greater_number


@engine.condition()
def second_condition(session):
    """
    Takes no argument and always returns True
    """
    return True


@engine.action("The Action")
def print_the_equation(
    session, lower_number: int = 10, greater_number: int = 20
) -> None:
    """
    Prints a statement Asserting that the first number is lower than the second number
    - lower_number: Number expected to be low
    - higher_number: Number expected to be high
    """
    print(f"{lower_number} < {greater_number}")


rule = {
    "conditions": [
        {
            "name": "first_condition",
            "args": {"lower_number": 3, "greater_number": 10},
        }
    ],
    "actions": [
        {
            "name": "print_the_equation",
            "args": {"lower_number": 3, "greater_number": 10},
        }
    ],
}


engine.run(rule)

Choices Fields

Choices fields are supported through python's built-in Enum type. Example:

from sauron.rule_engine import RuleEngine
from enum import Enum

class Color(str, Enum):
    red = "R"
    green = "G"
    blue = "B"


@engine.condition("is it red?")
def is_red(session, color: Color) -> bool:
    """
    Checks if the color is red
    """
    return color == color.red

Export Conditions and Actions

You can use the function export_metadata to export your data in a dict or as a json string (just pass json=True). Here is an Example and the output:

from sauron_rule_engine.rule_engine import RuleEngine
from enum import Enum

engine = RuleEngine()


@engine.condition("First Condition")
def first_condition(lower_number: int = 10, greater_number: int = 20) -> bool:
    """
    Checks if first number is lower than the first
    - lower_number: Number expected to be low
    - higher_number: Number expected to be high
    """
    return lower_number < greater_number


@engine.condition()
def second_condition():
    """
    Takes no argument and always returns True
    """
    return True


@engine.action("The Action")
def print_the_equation(
    lower_number: int = 10, greater_number: int = 20
) -> None:
    """
    Prints a statement Asserting that the first number is lower than the second number
    - lower_number: Number expected to be low
    - higher_number: Number expected to be high
    """
    print(f"{lower_number} < {greater_number}")


class Color(str, Enum):
    red = "R"
    green = "G"
    blue = "B"


@engine.condition("is it red?")
def is_red(color: Color) -> bool:
    """
    Checks if the color is red
    """
    return color == color.red


metadata = engine.export_metadata(json=True)
print(metadata)

Results in the following json to be served to your frontend:

{
  "actions": {
    "print_the_equation": {
      "args": {
        "lower_number": { "default": 10, "type": "int", "choices": null },
        "greater_number": { "default": 20, "type": "int", "choices": null }
      },
      "doc": "Prints a statement Asserting that the first number is lower than the second number\n- lower_number: Number expected to be low\n- higher_number: Number expected to be high",
      "name": "The Action"
    }
  },
  "conditions": {
    "first_condition": {
      "args": {
        "lower_number": { "default": 10, "type": "int", "choices": null },
        "greater_number": { "default": 20, "type": "int", "choices": null }
      },
      "doc": "Checks if first number is lower than the first\n- lower_number: Number expected to be low\n- higher_number: Number expected to be high",
      "name": "First Condition"
    },
    "second_condition": {
      "args": {},
      "doc": "Takes no argument and always returns True",
      "name": "second_condition"
    },
    "is_red": {
      "args": {
        "color": {
          "default": null,
          "type": "Color",
          "choices": ["red", "green", "blue"]
        }
      },
      "doc": "Checks if the color is red",
      "name": "is it red?"
    }
  }
}

Sessions

Results are stored in a result stack inside the session, so that jobs can share data with each other.

More Features coming to town

  • Support pydantic types
  • Support for complex types with hints to the frontend (like a range for an int type)

Contribute

  • We need all the help we can get. Please read CONTRIBUTE.md for instructions

Author

👤 João Ricardo Lhullier Lugão

Show your support

Give a ⭐️ if this project helped you!


This README was generated with ❤️ by readme-md-generator

Metadata

Release files for sauron-rule-engine 1.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sauron-rule-engine 1.0.4
File Size Uploaded
sauron-rule-engine-1.0.4.tar.gz 11.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sauron-rule-engine 1.0.4
File Interpreter ABI Platform
sauron_rule_engine-1.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 22.2 kB

Release files / sauron-rule-engine-1.0.4.tar.gz

Download URL sauron-rule-engine-1.0.4.tar.gz
Size 11.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ddebf20ecc3bc4d1508a1bede2d2659bab152132dad1eeafa987ef73aa50f9fb
BLAKE2b-256 checksum
How to use checksums
c7a2a95036642a59fcadc13c477f406a2cdad747df01779ae3e615db239a4a4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/0.12.17 CPython/3.7.4 Linux/4.4.0-18362-Microsoft

Release files / sauron_rule_engine-1.0.4-py3-none-any.whl

Download URL sauron_rule_engine-1.0.4-py3-none-any.whl
Size 11.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
673254cee17abdb3c4eb6e155c2346ec252aeb77857309031ca7e4521459e05e
BLAKE2b-256 checksum
How to use checksums
acc79c5769f9cce82a0fed755d1c38565140f80846eac790883666b3606973fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/0.12.17 CPython/3.7.4 Linux/4.4.0-18362-Microsoft

Release history Release notifications | RSS feed

This release

1.0.4 This release

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page