Rulify 🧠
A lightweight, chainable, and prioritized rule engine for Python that makes business logic management simple and elegant.
🚀 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 enginerun(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 rulecondition(callable): Function that returns True/False based on contextaction(callable): Function to execute when condition is Truepriority(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.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - 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
Metadata
Release files for rulify 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rulify-0.1.1.tar.gz | 14.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rulify-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.8 kB
Release files / rulify-0.1.1.tar.gz
| Download URL | rulify-0.1.1.tar.gz |
|---|---|
| Size | 14.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
29149921db2cb77fcd6a13e079dc318faa053523ad72cbf28037378b2faf8ed6
|
|
BLAKE2b-256 checksum How to use checksums |
345bb93709d756d98958bb3fed96d1b0229886e5af2e72d328371a86f920b781
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|
Release files / rulify-0.1.1-py3-none-any.whl
| Download URL | rulify-0.1.1-py3-none-any.whl |
|---|---|
| Size | 8.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d5835b3f57349cfdf15dd63e74527fc5c0953e934bd4fd2c8d197c7811954d23
|
|
BLAKE2b-256 checksum How to use checksums |
b30f500a7dfc786e95b855925d5f00b2b8a6af9acb699d5928e5533548781959
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|