A Python implementation of JsonLogic extended with
JSONPath-backed multi-value resolution via the vars operator.
Forked from the original json-logic-py and updated for Python 3.11+.
Developed and maintained by Bay Information Systems.
Operators
var -- scalar dot-path resolution
Resolves a single value from the data context using dot notation.
List indices are supported as integer path segments.
Returns None (or a supplied default) if the path does not exist.
jsonLogic({"var": "user.name"}, {"user": {"name": "Alice"}}) # "Alice" jsonLogic({"var": "items.0"}, {"items": ["a", "b"]}) # "a" jsonLogic({"var": ["missing", "default"]}, {}) # "default"
vars -- JSONPath multi-value resolution
Resolves multiple values from the data context using a
JSONPath expression (via jsonpath-ng). Always returns a list.
An empty list indicates no matches. An empty list is falsey in Python, so a failed match behaves correctly in boolean branch conditions without any special-casing.
var and vars are distinct operator keys and do not interact.
data = {"tags": ["a", "b", "c"]} jsonLogic({"vars": "tags[*]"}, data) # ["a", "b", "c"] jsonLogic({"vars": "steps[?type='image-eval'].output.score"}, state) # [0.9, 0.4] jsonLogic({"vars": "nothing[*]"}, {}) # [] -- falsey
Branch conditions in workflow definitions
var resolves scalar values for threshold comparisons:
rule = {">=": [{"var": "steps.safety_check.output.scores.unsafe"}, 0.7]} jsonLogic(rule, workflow_state) # False -- score is 0.1, do not halt
vars collects values across parallel step outputs for fan-in gates:
rule = {"==": [ {"count": [{"vars": "steps[?type='image-embed'].output.vector"}]}, 2 ]} jsonLogic(rule, workflow_state) # True -- both embed steps have produced output
Composite conditions combining both:
rule = { "and": [ {"<": [{"var": "steps.safety_check.output.scores.unsafe"}, 0.3]}, {">=": [{"var": "steps.aesthetic.output.scores.aesthetic"}, 0.7]}, ] }
List operations
map, filter, and reduce work against lists produced by vars:
# filter scores above threshold jsonLogic( {"filter": [{"vars": "scores[*]"}, {">=": [{"var": ""}, 0.7]}]}, {"scores": [0.9, 0.2, 0.75, 0.4]} ) # [0.9, 0.75] # sum all scores jsonLogic( {"reduce": [ {"vars": "scores[*]"}, {"+": [{"var": "accumulator"}, {"var": "current"}]}, 0 ]}, {"scores": [0.9, 0.2, 0.75]} ) # 1.85
Input wiring in workflow definitions
var for direct scalar input references (common case):
input: text: {"var": "steps.caption.output.text"}
vars for fan-out input references (all items at a path):
input: embeddings: {"vars": "steps[?type='image-embed'].output.vector"}
The executor sees a list at an input field and expands it into one dispatch
per item. vars is the declaration; the executor is the implementation of
the expansion.
Installation
pip install json-logic-path
For development:
pip install -e ".[dev]"
pytestCompatibility
- Python 3.11+
jsonpath-ngis required for thevarsoperator and is installed automatically. All other operators work without it.
Licence
MIT. See LICENSE for details.
This package is derived from json-logic-py by Nadir Izr, which is itself a Python port of json-logic-js by Jeremy Wadhams. Both are published under the MIT licence.
Developed and maintained by Bay Information Systems.