Skip to content

hardbyte/python-common-expression-language

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

57 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Python CEL - Common Expression Language

Documentation PyPI version Python 3.11+

Fast, Safe, and Expressive evaluation of Google's Common Expression Language (CEL) in Python, powered by Rust.

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 v0.14.0, providing microsecond-level expression evaluation with seamless Python integration.

πŸš€ Use Cases

  • πŸ›‘οΈ Policy Enforcement: Define access control rules that can be updated without code changes
  • βš™οΈ Configuration Validation: Validate complex settings with declarative rules
  • πŸ”„ Data Transformation: Transform and filter data with safe, portable expressions
  • πŸ“‹ Business Rules: Implement decision logic that business users can understand
  • πŸ” Query Filtering: Build dynamic filters for databases and APIs
  • 🎯 Feature Flags: Create sophisticated feature toggle conditions

Installation

pip install common-expression-language

Or using uv:

uv add common-expression-language

After installation, both the Python library and the cel command-line tool will be available.

πŸ“– Full Documentation: https://python-common-expression-language.readthedocs.io/

Quick Start

Python API

from cel import evaluate

# Simple expressions
result = evaluate("1 + 2")  # 3
result = evaluate("'Hello ' + 'World'")  # "Hello World"
result = evaluate("age >= 18", {"age": 25})  # True

# Complex expressions with context
result = evaluate(
    'user.role == "admin" && "write" in permissions',
    {
        "user": {"role": "admin"},
        "permissions": ["read", "write", "delete"]
    }
)  # True

Command Line Interface

# Simple evaluation
cel '1 + 2'  # 3

# With context
cel 'age >= 18' --context '{"age": 25}'  # true

# Interactive REPL
cel --interactive

Pre-compilation for Performance

When evaluating the same expression multiple times with different contexts, use compile() for better performance:

import cel

# Compile once
program = cel.compile("price * quantity > threshold")

# Execute many times - much faster than repeated evaluate() calls
result1 = program.execute({"price": 10, "quantity": 5, "threshold": 40})  # True
result2 = program.execute({"price": 5, "quantity": 3, "threshold": 20})   # False

Custom Functions

from cel import Context, evaluate

def calculate_discount(price, rate):
    return price * rate

context = Context()
context.add_function("calculate_discount", calculate_discount)
context.add_variable("price", 100)

result = evaluate("price - calculate_discount(price, 0.1)", context)  # 90.0

Real-World Example

from cel import evaluate, Context

# Access control policy
policy = """
user.role == "admin" || 
(resource.owner == user.id && current_hour >= 9 && current_hour <= 17)
"""

context = Context()
context.update({
    "user": {"id": "alice", "role": "user"},
    "resource": {"owner": "alice"},
    "current_hour": 14  # 2 PM
})

access_granted = evaluate(policy, context)  # True

Features

  • βœ… Fast Evaluation: Microsecond-level expression evaluation via Rust
  • βœ… Rich Type System: Integers, floats, strings, lists, maps, timestamps, durations, bytes, optionals
  • βœ… Python Integration: Seamless type conversion and custom function support (callable as f(x) or x.f())
  • βœ… Extended Standard Library: Optional strings, math, sets, encoders and lists extensions that mirror cel-go (see cel.stdlib)
  • βœ… Static Analysis: Inspect the variables and functions an expression references before running it (Program.references())
  • βœ… CLI Tools: Interactive REPL and batch processing capabilities
  • βœ… Safety First: Non-Turing complete, safe for untrusted expressions

Expression introspection

import cel

program = cel.compile("resource.owner == user.id && size(roles) > 0")
program.variables()  # ['resource', 'roles', 'user']
program.functions()  # ['_&&_', '_==_', '_>_', 'size']

Extended standard library

import cel
from cel.stdlib import add_stdlib_to_context

ctx = cel.Context()
add_stdlib_to_context(ctx)  # adds strings, math, sets, encoders, lists

cel.evaluate('"Hello World".lowerAscii()', ctx)   # 'hello world'
cel.evaluate("math.greatest([3, 1, 2])", ctx)     # 3
cel.evaluate("[1, 2, 3].contains(2)", ctx)        # True
cel.evaluate('base64.encode(b"hi")', ctx)         # 'aGk='

Portability note: CEL has no portable "bytecode". Cross-implementation interchange in the CEL ecosystem uses the protobuf AST (cel.expr.Expr / CheckedExpr), which the upstream cel Rust crate does not yet produce or consume. The portable artifact for this library is the CEL source string; use Program.references() for static analysis. See the docs for details.

Documentation

πŸ“š Complete documentation available at: https://python-common-expression-language.readthedocs.io/

Building Documentation Locally

To build and serve the documentation locally:

# Install documentation dependencies
uv sync --group docs

# Build the documentation
uv run --group docs mkdocs build

# Serve locally with live reload
uv run --group docs mkdocs serve

The documentation will be available at http://localhost:8000

Development

Testing

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=cel

# Test all documentation examples (embedded code + standalone files)
uv run --group docs pytest tests/test_docs.py -v

Building from Source

# Install development dependencies
uv sync --dev

# Build the package
uv run maturin develop

# Run tests
uv run pytest

Contributing

Contributions are welcome! Please see our documentation for:

  • CHANGELOG β€” release notes and behaviour changes
  • Development setup and guidelines
  • Areas where help is needed

License

This project is licensed under the same terms as the original cel-interpreter crate.

Resources

About

Python wrapper of a Rust CEL implementation

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors