Skip to main content

A JSON-based, server-side rule engine with a customizable decision table UI for non-technical end users

Project description

Banner

Documentation

Find detailed examples of using this SDK in our examples repository. General API reference documentation is available on our User Guide here.

Installation

Add this dependency to your project's build file:

pip install rulebricks
# or
poetry add rulebricks

Configuration

Before using the SDK, configure your API key. You can find your API key in your Rulebricks Dashboard.

from rulebricks import Rulebricks

rb = Rulebricks(
      base_url="https://rulebricks.com/api/v1",
      api_key="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Replace with your API key
)

Full SDK Example

A particularly comprehensive example of using the Rulebricks Python SDK can be found in the src/rulebricks/forge/examples/health_insurance_selector.py file.

This example programmatically constructs a rule, visualizes it locally, syncs it with a Rulebricks workspace, and solves the rule with a sample request.

Basic Usage

Using the SDK to interact with the Rulebricks API in a synchronous manner is simple.

Here's an example of how to use our Python SDK to solve a rule:

from rulebricks import Rulebricks

# Set the API key
rb = Rulebricks(
      base_url="https://rulebricks.com/api/v1",
      api_key="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Replace with your API key
)

result = rb.rules.solve(
    slug="tJOCd8XXXX",
    request={
        "customer_id": "anc39as3",
        "purchase_history": ["t-shirt", "mug"],
        "account_age_days": 4,
        "last_purchase_days_ago": 3,
        "email_subscription": False
    }
)

print(result)

Asynchronous Usage

For asynchronous API calls, access methods via the async_api attribute.

This allows you to leverage Python's asyncio library for non-blocking operations:

from rulebricks import AsyncRulebricks
import asyncio

# Set the API key
rb = AsyncRulebricks(
      base_url="https://rulebricks.com/api/v1",
      api_key="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Replace with your API key
)

async def main():
    async_result = await rb.rules.solve(
        slug="tJOCd8XXXX",
        request={
            "customer_id": "anc39as3",
            "purchase_history": ["t-shirt", "mug"],
            "account_age_days": 4,
            "last_purchase_days_ago": 3,
            "email_subscription": False
        }
    )
    print(async_result)

if __name__ == "__main__":
    asyncio.run(main())

Using a combination of solve, bulk_solve, parallel_solve and flows in synchronous or asynchronous modes gives you high flexibility to interact with the Rulebricks API in a way that best suits your application's needs.

Forge SDK

The Forge SDK is a powerful tool within the Rulebricks package that allows you to programmatically create and manage rules. It provides a flexible and intuitive way to define rule sets, conditions, and responses.

Looking for more comprehensive documentation? Read through our Forge SDK implementation examples.

Purpose

The Forge SDK enables you to:

  • Define complex and large rule structures
  • Create and manage conditions within rules
  • Specify request and response schemas
  • Generate rule representations in various formats (JSON, tabular, file)

Creating a Rule

Here's a simple example of creating a rule:

from rulebricks import Rulebricks
from rulebricks.forge import Rule

# Initialize a new rule
rule = Rule()

# Set basic metadata
rule.set_name("Customer Discount Rule") \
    .set_description("Determines customer discount eligibility based on purchase history")

# Define fields
purchase_count = rule.add_number_field("purchase_count", "Number of purchases", 0)
is_subscribed = rule.add_boolean_field("is_subscribed", "Newsletter subscription status", False)
customer_type = rule.add_string_field("customer_type", "Customer type", "regular")

# Define response fields
# Note we do not create variables for response fields
rule.add_boolean_response("discount_eligible", "Discount eligibility", False)
rule.add_number_response("discount_amount", "Discount percentage", 0)

# Add conditions
# By default, conditions are ANDed together
rule.when(
    purchase_count=purchase_count.greater_than(10), # "...and "
    is_subscribed=is_subscribed.equals(True), # "...and "
    customer_type=customer_type.equals("regular")
).then(
    discount_eligible=True,
    discount_amount=5
)

# Or, you can use `any` to OR your conditions
# rule.any(
#     purchase_count=purchase_count.less_than(10),
#     is_subscribed=is_subscribed.equals(False),
# ).then(
#     discount_eligible=False
# )

# Preview the rule locally
print(rule.to_table())

# Or, export the rule to a file
# rule.export()
#
# Or, publish the rule to your Rulebricks workspace
# rb = Rulebricks(
#       base_url="https://rulebricks.com/api/v1",
#       api_key="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Replace with your API key
# )
# rule.set_workspace(rb)
# rule.publish()

Field Types

These operators match the ones available to you when defining conditions in the Rulebricks decision table editor. We are always adding more operators, so the lists below likely will not be exhaustive.

Boolean Fields

Boolean fields support these operations:

boolean_field = rule.add_boolean_field("field_name")
boolean_field.equals(True)    # Check if true
boolean_field.equals(False)   # Check if false
boolean_field.any()           # Match any value

Number Fields

Number fields support these operations:

number_field = rule.add_number_field("field_name")
number_field.equals(value)                    # Exact match
number_field.not_equals(value)                # Not equal to
number_field.greater_than(value)              # Greater than
number_field.less_than(value)                 # Less than
number_field.greater_than_or_equal(value)     # Greater than or equal to
number_field.less_than_or_equal(value)        # Less than or equal to
number_field.between(start, end)              # Between two values (inclusive)
number_field.not_between(start, end)          # Not between two values
number_field.is_even()                        # Check if even
number_field.is_odd()                         # Check if odd
number_field.is_positive()                    # Check if positive
number_field.is_negative()                    # Check if negative
number_field.is_zero()                        # Check if zero
number_field.is_not_zero()                    # Check if not zero
number_field.is_multiple_of(value)            # Check if multiple of value
number_field.is_not_multiple_of(value)        # Check if not multiple of value
number_field.is_power_of(base)                # Check if power of base

String Fields

String fields support these operations:

string_field = rule.add_string_field("field_name")
string_field.contains(value)                # Contains substring
string_field.not_contains(value)            # Does not contain substring
string_field.equals(value)                  # Exact match
string_field.not_equals(value)              # Not equal to
string_field.is_empty()                     # Check if empty
string_field.is_not_empty()                 # Check if not empty
string_field.starts_with(value)             # Starts with prefix
string_field.ends_with(value)               # Ends with suffix
string_field.is_included_in(list)           # Value is in list
string_field.is_not_included_in(list)       # Value is not in list
string_field.contains_any_of(list)          # Contains any value from list
string_field.not_contains_any_of(list)      # Contains none from list
string_field.matches_regex(pattern)         # Matches regex pattern
string_field.not_matches_regex(pattern)     # Does not match regex
string_field.is_email()                     # Is valid email
string_field.is_not_email()                 # Is not valid email
string_field.is_url()                       # Is valid URL
string_field.is_not_url()                   # Is not valid URL
string_field.is_ip()                        # Is valid IP address
string_field.is_not_ip()                    # Is not valid IP address

Date Fields

Date fields support these operations:

date_field = rule.add_date_field("field_name")
date_field.is_past()                        # Date is in the past
date_field.is_future()                      # Date is in the future
date_field.days_ago(days)                   # Exact number of days ago
date_field.less_than_days_ago(days)         # Less than N days ago
date_field.more_than_days_ago(days)         # More than N days ago
date_field.days_from_now(days)              # Exact number of days from now
date_field.less_than_days_from_now(days)    # Less than N days from now
date_field.more_than_days_from_now(days)    # More than N days from now
date_field.is_today()                       # Is today
date_field.is_this_week()                   # Is this week
date_field.is_this_month()                  # Is this month
date_field.is_this_year()                   # Is this year
date_field.after(date)                      # After date
date_field.on_or_after(date)                # On or after date
date_field.before(date)                     # Before date
date_field.on_or_before(date)               # On or before date
date_field.between(start, end)              # Between two dates
date_field.not_between(start, end)          # Not between two dates

List Fields

List fields support these operations:

list_field = rule.add_list_field("field_name")
list_field.contains(value)                  # Contains value
list_field.is_empty()                       # Is empty list
list_field.is_not_empty()                   # Is not empty
list_field.length_equals(length)            # Has exact length
list_field.length_not_equals(length)        # Does not have length
list_field.longer_than(length)              # Longer than length
list_field.shorter_than(length)             # Shorter than length
list_field.contains_all(values)             # Contains all values
list_field.contains_any(values)             # Contains any value
list_field.contains_none(values)            # Contains none of values
list_field.equals(other)                    # Equals another list
list_field.not_equals(other)                # Not equal to list
list_field.has_duplicates()                 # Has duplicate values
list_field.no_duplicates()                  # Has no duplicates

Rule Operations

Exporting Rules

Rules can be exported to files:

# Export with default filename
filename = rule.export()

# Export to specific directory
filename = rule.export(directory="/path/to/directory")

JSON Conversion

Rules can be converted to and from JSON format:

# Convert rule to JSON string
json_str = rule.to_json()

# Convert rule to dictionary
dict_data = rule.to_dict()

# Create rule from JSON string
rule = Rule.from_json(json_str)

# Create rule from dictionary
rule = Rule.from_json(dict_data)

The from_json method accepts either a JSON string or a dictionary and will reconstruct the entire rule, including:

  • Basic metadata (name, description, etc.)
  • Request and response schemas
  • All conditions and their operators
  • Field definitions and types

Tabular Visualization

Rules can be visualized in a table format using the to_table() method:

# Print rule in table format
print(rule.to_table())

This will produce a grid-formatted table showing all conditions and their corresponding responses:

+---------------+---------------+-----------------+-------------------+
| age           | income        | customer_type   | discount          |
+===============+===============+=================+===================+
| greater than  | between       | equals          | 20                |
| (30)          | (50000,      | (premium)       |                   |
|               | 100000)       |                 |                   |
+---------------+---------------+-----------------+-------------------+
| less than     | greater than  | equals          | 10                |
| (30)          | (30000)       | (standard)      |                   |
+---------------+---------------+-----------------+-------------------+

The table format makes it easy to:

  • Visualize all conditions at once
  • Compare different conditions
  • Verify rule logic
  • Share rule definitions with stakeholders

Best Practices

  1. Field References: Store field references in variables when you need to use them multiple times:

    age = rule.add_number_field("age")
    # Use age variable in multiple conditions
    
  2. Chaining: Use method chaining for cleaner code:

    rule.set_name("My Rule").set_description("Description")
    
  3. Condition Organization: Group related conditions together:

    # Premium customer condition
    rule.when(
        customer_type=customer_type.equals("premium"),
        purchase_count=purchase_count.greater_than(100)
    ).then(
        discount=20
    )
    
  4. Meaningful Names: Use descriptive names for fields and rules:

    # Good
    purchase_history = rule.add_list_field("purchase_history")
    
    # Not as clear
    ph = rule.add_list_field("ph")
    

Migration Guide

If you're migrating from the old interface:

Old interface:

builder.update_condition(condition, "age", *number_op(NumberOperator.GREATER_THAN_OR_EQUAL_TO)(10))

New interface:

age = rule.add_number_field("age")
rule.when(age=age.greater_than_or_equal(10)).then(...)

The new SDK is easier to read, requires less code, and provides a better developer experience in modern IDEs.

Feedback and Contributions

Feedback is vital as we continue to improve the SDK and add more features. Please report any issues or suggest improvements through our GitHub issues page. Contributions to the SDK are welcome via pull requests.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rulebricks-2.5.0.tar.gz (97.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rulebricks-2.5.0-py3-none-any.whl (193.3 kB view details)

Uploaded Python 3

File details

Details for the file rulebricks-2.5.0.tar.gz.

File metadata

  • Download URL: rulebricks-2.5.0.tar.gz
  • Upload date:
  • Size: 97.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.8.18 Linux/6.11.0-1018-azure

File hashes

Hashes for rulebricks-2.5.0.tar.gz
Algorithm Hash digest
SHA256 10cc8a3f29d839c92b97538794c2627e5baea335b6e0b22b211e740081b048ba
MD5 311c2a579665174cd472603e69fc035f
BLAKE2b-256 0bd6cdbc780ce6d5adfd6c4f209fca444d74d3d0471e03f349e6400e67daa93d

See more details on using hashes here.

File details

Details for the file rulebricks-2.5.0-py3-none-any.whl.

File metadata

  • Download URL: rulebricks-2.5.0-py3-none-any.whl
  • Upload date:
  • Size: 193.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.8.18 Linux/6.11.0-1018-azure

File hashes

Hashes for rulebricks-2.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8d222e90b55d704e692a4bdfa4bc3384d56c3fac4d6bfc6b7e8e2af79cf3a4f3
MD5 ecf8389b67d109356b21cede6a3118ba
BLAKE2b-256 baed105903d5bba170663021d8d15d20ce714cf33ac0444410bb4014157252a9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page