Skip to main content

Rulify 🧠

A lightweight, chainable, and prioritized rule engine for Python that makes business logic management simple and elegant.

PyPI version Python 3.8+ License: MIT

🚀 Quick Start

pip install rulify
from rulify import Rule, RuleEngine

def is_hot(ctx): 
    return ctx["temp"] > 30

def turn_on_ac(ctx):
    ctx["ac"] = True
    print("AC turned ON")
    return ctx

# Create engine and add rules
engine = RuleEngine()
engine.add_rule(Rule("Hot Check", is_hot, turn_on_ac, priority=10))

# Run with context
context = {"temp": 35}
result = engine.run(context)
print(result)  # {'temp': 35, 'ac': True}

✨ Features

  • 🎯 Rule Prioritization: Execute rules in order of importance
  • 🔗 Rule Chaining: Chain rules together for complex workflows
  • ⚡ Lightweight: Zero external dependencies
  • 🐍 Pythonic: Clean, intuitive API design
  • 🔧 Flexible: Works with any Python data structure

📖 Documentation

Basic Usage

from rulify import Rule, RuleEngine

# Define conditions and actions
def is_high_temp(ctx): 
    return ctx.get("temp", 0) > 30

def cool_down(ctx): 
    ctx["ac"] = True
    ctx["fan_speed"] = "high"
    print("Cooling system activated")
    return ctx

def is_low_temp(ctx): 
    return ctx.get("temp", 0) < 20

def heat_up(ctx): 
    ctx["heater"] = True
    print("Heating system activated")
    return ctx

# Create engine and add rules
engine = RuleEngine()
engine.add_rule(Rule("Too Hot", is_high_temp, cool_down, priority=10))
engine.add_rule(Rule("Too Cold", is_low_temp, heat_up, priority=5))

# Process context
context = {"temp": 33}
result = engine.run(context)

Rule Chaining

def check_weather(ctx):
    return ctx.get("weather") == "rainy"

def grab_umbrella(ctx):
    ctx["umbrella"] = True
    print("Grabbed umbrella")
    return ctx

def check_location(ctx):
    return ctx.get("location") == "outdoor"

def stay_inside(ctx):
    ctx["location"] = "indoor"
    print("Staying inside")
    return ctx

# Chain rules together
umbrella_rule = Rule("Grab Umbrella", check_weather, grab_umbrella)
location_rule = Rule("Stay Inside", check_location, stay_inside, next_rule=umbrella_rule)

engine = RuleEngine()
engine.add_rule(location_rule)

context = {"weather": "rainy", "location": "outdoor"}
result = engine.run(context)

Advanced Example: E-commerce Order Processing

def is_vip_customer(ctx):
    return ctx.get("customer_tier") == "VIP"

def apply_vip_discount(ctx):
    ctx["discount"] = 0.15
    ctx["priority_shipping"] = True
    print("VIP discount applied")
    return ctx

def is_high_value_order(ctx):
    return ctx.get("order_total", 0) > 1000

def apply_bulk_discount(ctx):
    ctx["discount"] = ctx.get("discount", 0) + 0.10
    print("Bulk discount applied")
    return ctx

def is_express_shipping(ctx):
    return ctx.get("shipping_type") == "express"

def calculate_shipping_cost(ctx):
    base_cost = 10
    if ctx.get("priority_shipping"):
        base_cost += 5
    ctx["shipping_cost"] = base_cost
    return ctx

# Build order processing engine
engine = RuleEngine()
engine.add_rule(Rule("VIP Customer", is_vip_customer, apply_vip_discount, priority=20))
engine.add_rule(Rule("High Value", is_high_value_order, apply_bulk_discount, priority=15))
engine.add_rule(Rule("Express Shipping", is_express_shipping, calculate_shipping_cost, priority=10))

# Process order
order = {
    "customer_tier": "VIP",
    "order_total": 1200,
    "shipping_type": "express"
}

result = engine.run(order)
print(result)

🛠️ API Reference

RuleEngine

The main engine for managing and executing rules.

Methods

  • add_rule(rule): Add a rule to the engine
  • run(context): Execute all rules against the given context

Rule

Represents a single rule with condition, action, and metadata.

Constructor

Rule(name, condition, action, priority=0, next_rule=None)
  • name (str): Human-readable name for the rule
  • condition (callable): Function that returns True/False based on context
  • action (callable): Function to execute when condition is True
  • priority (int): Higher numbers execute first (default: 0)
  • next_rule (Rule): Optional rule to chain after this one

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Inspired by business rule engines and workflow management systems
  • Built with simplicity and performance in mind

Made with ❤️ by Ertuğrul Kara

Download files

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

Source Distribution

rulify-0.1.1.tar.gz (14.3 kB view details)

Uploaded Source

Built Distribution

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

rulify-0.1.1-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file rulify-0.1.1.tar.gz.

File metadata

  • Download URL: rulify-0.1.1.tar.gz
  • Upload date:
  • Size: 14.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.7

File hashes

Hashes for rulify-0.1.1.tar.gz
Algorithm Hash digest
SHA256 29149921db2cb77fcd6a13e079dc318faa053523ad72cbf28037378b2faf8ed6
MD5 9040d3e00611ce18e50844a32c411280
BLAKE2b-256 345bb93709d756d98958bb3fed96d1b0229886e5af2e72d328371a86f920b781

See more details on using hashes here.

File details

Details for the file rulify-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: rulify-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.7

File hashes

Hashes for rulify-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d5835b3f57349cfdf15dd63e74527fc5c0953e934bd4fd2c8d197c7811954d23
MD5 a91f151258bc244a6d327ad63c8b2330
BLAKE2b-256 b30f500a7dfc786e95b855925d5f00b2b8a6af9acb699d5928e5533548781959

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 files

Supported by

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