A safe, embeddable expression language for Python, powered by Rust, ideal for access control, validation, and data transformation.
Python CEL¶
Evaluate business rules, filters, and policies at microsecond speeds â in pure Python code.
The Common Expression Language (CEL) is a non-Turing complete language designed for simplicity, speed, and safety. This Python package wraps the Rust implementation cel, providing fast and safe CEL expression evaluation with seamless Python integration.
Quick Start Paths¶
Simple evaluation
from cel import evaluate
result = evaluate("age > 21", {"age": 25})
assert result == True # â True (age check passes)
Policy checks
policy = "user.role == 'admin' || resource.public"
result = evaluate(policy, {"user": {"role": "guest"}, "resource": {"public": True}})
assert result == True # â True (public resource access allowed)
Nested data
user_data = {
"user": {
"name": "Alice",
"profile": {"verified": True, "role": "admin"}
}
}
# Access nested fields and business logic
name_check = evaluate("user.name == 'Alice'", user_data)
assert name_check == True # â True (name matches)
policy = "user.profile.verified && user.profile.role == 'admin'"
admin_access = evaluate(policy, user_data)
assert admin_access == True # â True (verified admin user)
print("â Basic CEL evaluation working correctly") # â â Basic CEL evaluation working correctly
// Basic types and operations
1 + 2 * 3 // â 7
"hello" + " " + "world" // â "hello world"
[1, 2, 3][1] // â 2
{"name": "Alice"}.name // â "Alice"
// Conditionals and logic
age >= 18 ? "adult" : "minor"
has(user.email) && user.email.endsWith("@company.com")
// Collection operations
users.filter(u, u.active).all(u, u.verified)
emails.exists(e, e.endsWith("@company.com"))
// Built-in functions
size([1, 2, 3]) // â 3
timestamp("2024-01-01T00:00:00Z")
duration("1h30m")
Key Features¶
â
80% CEL spec compliance
â
200+ tests
â
CLI + Python API
â
Safe by design (Rust core)
â
Ready for production
â
No GIL-blocking, safe concurrent evaluation
â
Strict type safety (CEL-compliant type system)
Why Python CEL?¶
ð Performance¶
Built on Rust with PyO3 - evaluate expressions in microseconds, not milliseconds.
| Expression Type | Evaluation Time | Throughput | vs Pure Python |
|---|---|---|---|
Simple (x + y * 2) |
5-15 Ξs | 50,000+ ops/sec | ~10x faster |
| Complex (multi-condition policies) | 15-40 Ξs | 25,000+ ops/sec | ~20x faster |
| Function calls (with custom Python functions) | 20-50 Ξs | 20,000+ ops/sec | ~5x faster |
| Pure Python equivalent | 100-800 Ξs | 1,000-10,000 ops/sec | baseline |
Performance varies by hardware. See examples/performance/compile_execute_benchmark.py to run your own benchmarks.
ðĄïļ Safety¶
Safe by Design: Built on a memory-safe Rust core. The non-Turing complete nature of CEL prevents infinite loops, and comprehensive error handling traps evaluation errors as Python exceptions.
ðŊ Production Ready¶
380+ tests, comprehensive CLI, type safety, and high CEL spec compliance.
ð Up to Date¶
Built on cel-rust 0.13 â tracks upstream improvements in correctness and performance.
ð§ Developer Friendly¶
Dual interfaces (Python API + CLI), rich error messages, extensive documentation, and full IDE support.
How It Works¶
Python CEL leverages a high-performance Rust core wrapped with PyO3 for seamless Python integration:
graph LR
A[Python Application] --> B[python-cel Package]
B --> C[PyO3 Boundary]
C --> D[cel Rust Crate]
subgraph PL ["Python Layer"]
B
E[evaluate function]
F[Context class]
G[Type conversion]
end
subgraph RL ["Rust Layer"]
D
H[CEL Parser]
I[Expression Evaluator]
J[Type System]
end
B --> E
B --> F
B --> G
D --> H
D --> I
D --> J
style A fill:#3776ab,color:#fff
style D fill:#ce422b,color:#fff
style C fill:#f39c12,color:#fff
Why This Architecture?
- ð Speed: Rust's zero-cost abstractions deliver microsecond-level performance
- ðĄïļ Safety: Memory-safe Rust prevents crashes and security vulnerabilities
- ð§ Ergonomics: PyO3 provides seamless Python integration with automatic type conversion
- ðĶ Distribution: Single wheel package with no external dependencies
- ⥠Concurrency: No GIL-blocking â safe concurrent evaluation across threads
Installation¶
After installation, both the Python library and the cel command-line tool will be available.
Real-World Example: Access Control¶
from cel import evaluate
# Multi-factor access control policy
policy = """
user.verified &&
(user.role == "admin" || resource.owner == user.id || resource.public)
"""
# Test different scenarios
admin_user = {"user": {"role": "admin", "verified": True, "id": "admin1"}, "resource": {"owner": "bob", "public": False}}
owner_user = {"user": {"role": "user", "verified": True, "id": "alice"}, "resource": {"owner": "alice", "public": False}}
guest_user = {"user": {"role": "guest", "verified": True, "id": "guest1"}, "resource": {"owner": "bob", "public": True}}
assert evaluate(policy, admin_user) == True # â True (admin access granted)
assert evaluate(policy, owner_user) == True # â True (owner access granted)
assert evaluate(policy, guest_user) == True # â True (public resource access)
print("â Access control policies working correctly") # â â Access control policies working correctly
Simple, readable policies that handle complex business logic.
â Learn Enterprise-Grade Access Control
Next Steps¶
ð Get Started: - Installation - Get up and running in 2 minutes - Quick Start - Your first CEL expressions
ð Learn CEL: - Thinking in CEL - Core concepts and philosophy - CEL Language Basics - Complete syntax reference - Your First Integration - Python API fundamentals - Extending CEL - Advanced context and custom functions
ð ïļ Solve Problems: - Access Control Policies - Permission systems - Business Logic & Data Transformation - Business rules - Dynamic Query Filters - Build safe, dynamic queries - Error Handling - Exceptions and safe-evaluation patterns