This is an expression language python package.
Project description
Dilemma Expression Language
A secure, powerful expression evaluation engine for Python applications that makes complex logical expressions readable and maintainable.
Why Dilemma?
Instead of writing complex Python conditionals like this:
if (user.get('profile', {}).get('age', 0) >= 18 and
user.get('subscription', {}).get('status') == 'active' and
datetime.now() - user.get('last_login', datetime.min) < timedelta(days=30)):
# grant access
pass
Write this:
from dilemma import evaluate
expr = "user.profile.age >= 18 and user.subscription.status == 'active' and user.last_login upcoming within 30 days"
if evaluate(expr, context):
# grant access
pass
Features
- Secure evaluation - No arbitrary code execution, only safe expressions
- Rich data access - Navigate nested dictionaries and lists with ease
- Date/time operations - Natural language date comparisons
- Multiple resolvers - JsonPath, JQ, and basic dictionary lookup
- Performance optimized - Compile expressions once, evaluate many times
- Type safe - Built-in type checking and validation
Quick Start
pip install dilemma
from dilemma import evaluate
# Basic arithmetic and logic
result = evaluate("2 * (3 + 4)") # Returns 14
result = evaluate("age >= 18 and status == 'active'", {"age": 25, "status": "active"})
# Date operations
result = evaluate("user.last_login upcoming within 7 days", context)
result = evaluate("subscription.end_date is $future", context)
# Complex data access
result = evaluate("user.permissions contains 'admin'", context)
result = evaluate("`[.users[] | select(.active == true) | .name] | length` > 0", context)
Language Features
All Language Features. Extensive Examples.
Data Access Patterns
# Dot notation for nested objects
"user.profile.settings.theme == 'dark'"
# Natural possessive syntax
"user's subscription's status == 'premium'"
# Array/list access
"users[0].name == 'Alice'"
# Check membership
"'admin' in user.roles"
"user.permissions contains 'read'"
Date and Time Operations
# Relative time checks
"user.created_at upcoming within 30 days"
"order.shipped_date older than 1 week"
# State comparisons
"subscription.expires is $future"
"last_backup is $past"
"meeting.date is $today"
# Date comparisons
"start_date before end_date"
"event.date same_day_as $now"
Advanced JQ Integration
For complex data manipulation, use JQ expressions in backticks:
# Filter and transform arrays - working with provided context
evaluate('`[.users[] | select(.active == true) | .name]`', context)
# Mathematical operations on arrays
evaluate('`[.sales[].amount] | add` > 10000', context)
# Complex conditionals
evaluate('`[.products[] | select(.price > 100 and .category == "electronics")] | length` > 1', context)
Performance Optimization
For repeated evaluations, compile expressions once:
from dilemma import compile_expression
# Compile once
eligibility_check = compile_expression(
"user.age >= 18 and user.subscription.active and user.last_login upcoming within 30 days"
)
# Evaluate many times with different contexts
for user_data in users:
if eligibility_check.evaluate(user_data):
# send_premium_content(user_data)
pass
Error Handling
Dilemma provides clear, actionable error messages:
try:
result = evaluate("user.invalidfield == 'test'", context)
except VariableError as e:
print(f"Expression error: {e}")
# Suggests available fields and common fixes
Use Cases
- Form validation rules -
"email like '*@*' and age >= 13" - Business logic -
"order.total > 100 and customer.tier == 'premium'" - Access control -
"user.roles contains 'admin' or resource.owner == user.id" - Data filtering -
"created_at upcoming within 24 hours and status == 'pending'" - Workflow conditions -
"approval.status == 'approved' and budget.remaining >= cost"
Safety & Security
- ✅ No arbitrary Python code execution
- ✅ No access to imports or builtins
- ✅ Sandboxed evaluation environment
- ✅ Input validation and sanitization
- ✅ Memory and complexity limits
License
MIT License - see LICENSE file for details.
Project details
Release history Release notifications | RSS feed
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 dilemma-0.3.4.tar.gz.
File metadata
- Download URL: dilemma-0.3.4.tar.gz
- Upload date:
- Size: 134.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51d0f8036bc532de53e9fb33fc4b9933e04468f1bde6b75dfc7706ca3c658d9b
|
|
| MD5 |
d99f42ed15a2fe2f02edb8e4ba34a1a2
|
|
| BLAKE2b-256 |
9bdd36da630d7bc81f43e8ad5ce8fd2f993f95a7747724d25d4dafc2d32235eb
|
File details
Details for the file dilemma-0.3.4-py3-none-any.whl.
File metadata
- Download URL: dilemma-0.3.4-py3-none-any.whl
- Upload date:
- Size: 36.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9c0cbd641974afee9e93581c43785fa3c1ee7ddd7b8e5eb40fa02575a614910
|
|
| MD5 |
241ccc9c29ee0d7319e70d5c101fed64
|
|
| BLAKE2b-256 |
3382b6f040fc41a16f73274738c8a268fcecd43f4e03eec5cc832421807676f4
|