rudy-ab-test
A lightweight, rule-based feature-flag and A/B test engine for Python.
Define variables with fallback defaults, attach prioritized rules driven by arbitrary context dicts, and evaluate them at runtime — no external services required.
Installation
pip install rudy-ab-test
Quick start
from rudy_ab_test import RuleEngine, Variable, Rule, Condition
engine = RuleEngine()
rule = Rule(
name="premium_model_for_prod",
conditions=[Condition(field="environment", operator="eq", value="prod")],
result="gpt-4",
priority=1,
)
engine.register(Variable(name="model_name", default="gpt-3.5-turbo", rules=[rule]))
result = engine.evaluate("model_name", {"environment": "prod"})
# → "gpt-4"
Core concepts
Condition
A single predicate evaluated against the context dict.
| Field | Type | Description |
|---|---|---|
field |
str |
Key looked up in the context dict |
operator |
str |
Comparison operator (see table below) |
value |
Any |
Right-hand side of the comparison |
Supported operators
| Operator | Meaning |
|---|---|
eq |
context[field] == value |
neq |
context[field] != value |
in |
context[field] in value |
not_in |
context[field] not in value |
gt |
context[field] > value |
gte |
context[field] >= value |
lt |
context[field] < value |
lte |
context[field] <= value |
starts_with |
str(context[field]).startswith(...) |
ends_with |
str(context[field]).endswith(...) |
Rule
A rule fires when all its conditions match. The first matching rule (by descending priority) determines the variable's value.
| Field | Type | Description |
|---|---|---|
name |
str |
Unique identifier (for debugging/logging) |
conditions |
list[Condition] |
All must match (AND logic) |
result |
Any |
Value returned when this rule fires |
priority |
int |
Higher value → evaluated first (default 0) |
Variable
A named configuration point with a default value and an ordered list of rules.
| Field | Type | Description |
|---|---|---|
name |
str |
Variable identifier |
default |
Any |
Returned when no rule matches |
rules |
list[Rule] |
Evaluated in descending priority order |
RuleEngine
Central registry. Stores variables and evaluates them against a context dict.
Usage
Evaluating a single variable
value = engine.evaluate("retriever_provider", context)
Evaluating multiple variables at once
Pass a list of names to get a dict back:
results = engine.evaluate(["retriever_provider", "model_name", "environment"], context)
# → {"retriever_provider": "aws", "model_name": "gpt-3.5-turbo", "environment": "dev"}
Multiple conditions (AND logic)
All conditions in a rule must match for the rule to fire:
rule = Rule(
name="aws_for_application",
conditions=[
Condition(field="system_type", operator="eq", value="application"),
Condition(field="token_hash", operator="starts_with", value="xpto"),
Condition(field="token_hash", operator="ends_with", value="abc123"),
],
result="aws",
priority=1,
)
Priority
Rules are sorted by descending priority on register(). When two rules could match, the one with the highest priority wins:
rule_high = Rule(name="r1", conditions=[...], result="aws", priority=2)
rule_low = Rule(name="r2", conditions=[...], result="bridge", priority=1)
# rule_high is evaluated first
Serialization — export and reload
Variables can be serialized to plain dicts (e.g. to store in a database or config file) and reloaded:
payload = engine.export_variables() # list[dict]
# ... save to DB / JSON file ...
new_engine = RuleEngine()
new_engine.load_variables(payload)
Complete example
from rudy_ab_test import RuleEngine, Variable, Rule, Condition
engine = RuleEngine()
# --- retriever_provider ---
engine.register(Variable(
name="retriever_provider",
default="bridge",
rules=[
Rule(
name="aws_for_privileged_users",
conditions=[
Condition(field="system_type", operator="eq", value="user"),
Condition(field="function", operator="in", value=["SPECIALIST_1", "SUPERINTENDENT"]),
],
result="aws",
priority=2,
),
Rule(
name="aws_for_verified_apps",
conditions=[
Condition(field="system_type", operator="eq", value="application"),
Condition(field="token_hash", operator="starts_with", value="xpto"),
Condition(field="token_hash", operator="ends_with", value="abc123"),
],
result="aws",
priority=1,
),
],
))
# --- model_name ---
engine.register(Variable(
name="model_name",
default="gpt-3.5-turbo",
rules=[
Rule(name="prod_model", conditions=[Condition(field="environment", operator="eq", value="prod")], result="gpt-4", priority=1),
Rule(name="dev_model", conditions=[Condition(field="environment", operator="eq", value="dev")], result="gpt-3.5-turbo", priority=2),
],
))
# Evaluate a privileged user
user_ctx = {"system_type": "user", "function": "SPECIALIST_1", "environment": "dev"}
print(engine.evaluate(["retriever_provider", "model_name"], user_ctx))
# → {"retriever_provider": "aws", "model_name": "gpt-3.5-turbo"}
# Evaluate a standard user
anon_ctx = {"system_type": "user", "function": "JUNIOR_ANALIST", "environment": "dev"}
print(engine.evaluate(["retriever_provider", "model_name"], anon_ctx))
# → {"retriever_provider": "bridge", "model_name": "gpt-3.5-turbo"}
Requirements
- Python ≥ 3.10
License
MIT
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
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rudy_ab_test-0.1.0.tar.gz.
File metadata
- Download URL: rudy_ab_test-0.1.0.tar.gz
- Upload date:
- Size: 6.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1a3854fa18dd2a88ed05b4ea2f2c3e0d7a9ab6010f65346805a7e9894555451
|
|
| MD5 |
32488eb1d8158338ad02416426ef2f1f
|
|
| BLAKE2b-256 |
c87ea943257f188bd50ace0baf7ac6fa80edcaa5f309a040945e5f9b2e98279d
|
File details
Details for the file rudy_ab_test-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rudy_ab_test-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e649c5b99aabc4dbe5f7c2294427f0c67b07e5fa845b1ee2b5c02f6318bcf32e
|
|
| MD5 |
bd34f4aa574842463260cda871795aac
|
|
| BLAKE2b-256 |
6b4832d3351c913f2e707a9fdc323478970259ce7752d504eabd5abecdb93d34
|