Dynamic-Expressions
A Python library for building, evaluating, and serializing expression trees. Compose rules as immutable AST nodes, evaluate them asynchronously with a visitor dispatcher, persist them as JSON and parse the ones from python-like code or JSON.
Features
- Immutable node trees — hashable dataclasses suitable for caching and comparison
- Visitor pattern — swap evaluation behavior per node type without changing the tree
- Context DSL — compose rules with Python operators (
&,|,==,in_, …) - Serialization & Parsing — Pydantic JSON schemas and AST string parsers
- Caching — Redis-backed cache extensions with configurable policies
- Middlewares — wrap visitor calls for logging, timing, etc
Installation
With all optional dependencies:
Minimal example
import asyncio
from dynamic_expressions.dispatcher import VisitorDispatcher
from dynamic_expressions.nodes import BinaryExpressionNode, LiteralNode
from dynamic_expressions.types import EmptyContext
from dynamic_expressions.visitors import BinaryExpressionVisitor, LiteralVisitor
dispatcher = VisitorDispatcher[EmptyContext](
visitors={
LiteralNode: LiteralVisitor(),
BinaryExpressionNode: BinaryExpressionVisitor(),
},
)
node = BinaryExpressionNode(
operator="+",
left=LiteralNode(value=1),
right=LiteralNode(value=2),
)
async def main() -> None:
result = await dispatcher.visit(node, None)
assert result == 3
asyncio.run(main())
Documentation map
| Section | Description |
|---|---|
| Getting started | Quickstart in five minutes |
| Concepts | Architecture, nodes, visitors, dispatcher, DSL |
| Advanced | Custom nodes, extensions, middlewares |
| Serialization | Pydantic, AST, MsgSpec |
| Cookbook | End-to-end recipes |
Next steps
Continue with Getting started or jump to the Basic cookbook for a typed access-control scenario.