No project description provided
Project description
genruler
A rule DSL language parser in Python that allows you to write and evaluate rules using a LISP-inspired syntax.
Table of Contents
Quick Start
import genruler
# Parse a simple rule
rule = genruler.parse('(condition.equal (basic.field "name") "John")')
# Apply the rule to a context
context = {"name": "John"}
result = rule(context) # Returns True
Installation
You can install genruler directly from PyPI:
pip install genruler
Alternatively, you can install from source:
git clone https://github.com/jeffrey04/genruler.git
cd genruler
pip install -e .
Requirements
- Python 3.12 or higher (less than 3.14)
Ruler DSL
This mini-language is partially inspired by LISP. A rule is represented by a an s-expression.
Syntax & Structure
(namespace.function_name "some_arguments" "more_arguments_if_applicable")
A rule is usually consist of a function name, and a list of (sometimes optional) arguments. Function names are often namespaced (e.g. "boolean.and"
, "condition.equal"
etc.) and usually only recognized if placed in the first elemnt.
Unless otherwise specified, a rule can be inserted as an argument to another rule, for example a boolean.and
rule.
(boolean.and (condition.equal (basic.field "fieldA") "X"),
condition.equal (basic.field "fieldB") "Y")
Parsing and computing result
In order to parse the rule, just call genruler.parse
. The result is a function where you can put in a context object in order for it to compute a result.
import genruler
rule = genruler.parse('(condition.Equal (basic.Field "fieldA") "X")')
context = {"fieldA": "X"}
rule(context) // should return true
Ruler API overview
Array functions
Some array related functions.
array.length
(array.length $argument)
Returns the length of a given array $argument
. For example,
import genruler
rule = genruler.parse('(array.length (basic.Field "fieldA"))')
context = {"fieldA": [1, 2, 3]}
rule(context) // should return 3
Basic functions
Some random functions that don't fit anywhere else goes here
basic.context
(basic.context $context_sub, $rule)
Temporarily change the context to $context_sub
, and perform $rule
with $context_sub
as the new context
$context_sub
(required): A struct, or a rule to extract a new struct w.r.t. the originalcontext
$rule
(required): the rule to be applied w.r.t.$context_sub
An example:
rule = ruler.parse('(basic.Context (basic.field, 'sub')
(basic.field, 'foo'))')
context = {"sub": {"foo": "bar"}}
rule(context) # returns context['sub']['foo'], which is 'bar'
Basic.field
(basic.field $key $default)
Returns a field value from context
when called.
$key
(required): is akey
in thecontext
.$default
(optional): is a default value to be returned whencontext[key]
does not exist.
basic.value
(basic.value $value)
Returns a value, regardless what is in the context
$value
(required): a value to return. MAY NOT be a sub-rule
Boolean operators
Usually used to chain condition rules (see next section) together
boolean.and
(boolean.and $argument1 $argument2 ...)
Returns True
if all arguments returns True
, or False
otherwise.
boolean.contradiction
(boolean.contradiction)
Always returns a False
, a shorthand for
(basic.Value false)
boolean.not
(boolean.not $argument)
Returns the result of negation done to $argument
.
boolean.or
(boolean.or $argument2 $argument2)
Returns True
if any of the arguments is True
, or False
otherwise.
boolean.tautology
(boolean.tautology)
Returns True
regardless
Condition rules
Usually returns either true or false
condition.equal
(condition.equal $alpha $beta)
Returns True
if and only if $alpha
is equivalent to $beta
.
condition.gt
(condition.gt $alpha $beta)
Returns True
if and only if $alpha
is greater than $beta
.
condition.ge
(condition.ge $alpha $beta)
Returns True
if and only if $alpha
is greater than or equal to $beta
.
condition.in
(condition.in $alpha $values)
Returns True
if $alpha
is in $values
condition.is_none
(condition.is_none $alpha)
Returns True
if $alpha
is None
condition.is_true
(condition.Is_True $alpha)
Returns True
if $alpha
is True
condition.lt
(condition.less_than $alpha $beta)
Returns True
if and only if $alpha
is less than $beta
.
condition.le
["condition.Less_Than_Equal", $alpha, $beta]
Returns True
if and only if $alpha
is less than or equal to $beta
.
String operations
Some basic string operations
string.concat
(string.Concat $link $argument1 $argument2 ...)
Concatenate arguments by $link
string.concat_fields
(string.concat_fields $link $key1 $key2 ...)
A short hand for
(string.concat $link (string.Field $key1) (string.field $key2) ...)
Note: $key1
, $key2
etc.
string.lower
(string.lower $value)
Change $value
to lowercase
Error Handling
When using ruler, you might encounter these common errors:
- Syntax Errors: Occur when the rule string is not properly formatted
- Context Key Errors: When accessing non-existent fields in the context
- Type Errors: When comparing incompatible types
Example of handling errors:
try:
rule = genruler.parse('(condition.equal (basic.field "age") 25)')
result = rule({}) # Empty context
except KeyError:
print("Field not found in context")
except Exception as e:
print(f"An error occurred: {str(e)}")
Contributing
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a new branch (
git checkout -b feature/improvement
) - Make your changes
- Run the tests (
python -m pytest
) - Commit your changes (
git commit -am 'Add new feature'
) - Push to the branch (
git push origin feature/improvement
) - Create a Pull Request
License
This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.
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
Built Distribution
File details
Details for the file genruler-0.1.2.tar.gz
.
File metadata
- Download URL: genruler-0.1.2.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.4 CPython/3.12.7 Linux/6.11.0-8-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0cfd4e5c5a4c361e41ad0c8188c97b5a301a27a770506d82d7c414ee7c88e08c |
|
MD5 | 53d20a8bead798b69c839fe9761db1d3 |
|
BLAKE2b-256 | 1ed8aac0664f6906275e31100329ad8f569ddf2bee8b15d02d928013e169a1fe |
File details
Details for the file genruler-0.1.2-py3-none-any.whl
.
File metadata
- Download URL: genruler-0.1.2-py3-none-any.whl
- Upload date:
- Size: 10.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.4 CPython/3.12.7 Linux/6.11.0-8-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | df2f2d5fc54d93546cac3f56e4dd3a991ee4c714bb1bda13079364b149739b25 |
|
MD5 | b677877995aa5701dfafa0c0400028d3 |
|
BLAKE2b-256 | 22642b8a5445b5c2c3cbb242f1dcf65bc0d3ee969cd1bae102fa197d682df7ae |