Installation
Basic usage
Loader
Pass aloader option to ZenEngine to serve decisions by key. Use a declarative config for common backends, or a callback for custom ones.
Static
Register decisions in memory. Use this when your rules ship with the application or are already loaded:File system
Load decisions from files under a root directory. Keys resolve to paths relative topath:
Zip archive
Pass the bytes of a zip archive. Every.json entry becomes a decision keyed by its path within the archive. This pairs naturally with BRMS release ZIPs - download the release from object storage and hand the bytes to the engine:
Custom loader
For any other backend, pass a callback that receives the decision key and returns its content:async function - see Async support.
Batch evaluation
Evaluate many requests in one call. Each result reports its own success or failure, so one bad input never fails the batch:Async support
Useasync_evaluate for non-blocking evaluation:
Error handling
Tracing
Enable tracing to inspect decision execution:Expression utilities
Evaluate ZEN expressions outside of a decision context:Spark integration
For distributed processing at scale, see PySpark and AWS Glue.Best practices
UseZenDecisionContent for caching. Pre-compiling decisions avoids repeated parsing overhead. Cache compiled content in a dict keyed by decision name.
Initialize the engine once. Create a single ZenEngine instance at application startup and reuse it for all evaluations.
Implement a loader for dynamic decisions. The loader pattern centralizes decision loading logic and enables caching at the source.
Use async evaluation for concurrent workloads. When evaluating multiple decisions, use async_evaluate with asyncio.gather for better throughput.