Skip to main content

Pure Python CEL Implementation

Project description

Travis Build Status Requirements Status Apache License

Pure Python implementation of Google Common Expression Language, https://opensource.google/projects/cel.

The Common Expression Language (CEL) implements common semantics for expression evaluation, enabling different applications to more easily interoperate.

Key Applications

Security policy: organization have complex infrastructure and need common tooling to reason about the system as a whole

Protocols: expressions are a useful data type and require interoperability across programming languages and platforms.

This implementation has minimal dependencies, runs quickly, and can be embedded into Python-based applications. Specifically, the intent is to be part of Cloud Custodian, C7N, as part of the security policy filter.

Installation

pip install cel-python

You now have the CEL run-time available to Python-based applications.

Command Line

We can read JSON directly from stdin, making this a bit like jq.

% python -m celpy '.this.from.json * 3 + 3' <<EOF
heredoc> {"this": {"from": {"json": 13}}}
heredoc> EOF
42

It’s also a desk calculator, like expr, but with float values:

% python -m celpy -n '355.0 / 113.0'
3.1415929203539825

It’s not as sophistcated as bc. But, yes, this has a tiny advantage over python -c '355/113'. Most notably, the ability to embed Google CEL into other contexts where you don’t really want Python’s power.

It’s also capable of decision-making, like test:

% echo '{"status": 3}' | python -m celpy -sb '.status == 0'
false
% echo $?
1

We can provide a -a option to define objects with specific data types. This is particularly helpful for providing protobuf message definitions.

python -m celpy -n --arg x:int=6 --arg y:int=7 'x*y'
42

If you want to see details of evaluation, use -v.

python -m celpy -v -n '[2, 4, 6].map(n, n/2)'
... a lot of output
[1, 2, 3]

Library

To follow the pattern defined in the Go implementation, there’s a multi-step process for compiling a CEL expression to create a runnable “program”. This program can then be applied to argument values.

>>> import celpy
>>> cel_source = """
... account.balance >= transaction.withdrawal
... || (account.overdraftProtection
... && account.overdraftLimit >= transaction.withdrawal - account.balance)
... """

>>> env = celpy.Environment()
>>> ast = env.compile(cel_source)
>>> prgm = env.program(ast)

>>> activation = {
...     "account": celpy.json_to_cel({"balance": 500, "overdraftProtection": False}),
...     "transaction": celpy.json_to_cel({"withdrawal": 600})
... }
>>> result = prgm.evaluate(activation)
>>> result
BoolType(False)

The Python classes are generally based on the object model in https://github.com/google/cel-go These types semantics are slightly different from Python’s native semantics. Type coercion is not generally done. Python // truncates toward negative infinity. Go (and CEL) / truncates toward zero.

Development

The parser is based on the grammars used by Go and C++, but processed through Python Lark.

See https://github.com/google/cel-spec/blob/master/doc/langdef.md

https://github.com/google/cel-cpp/blob/master/parser/Cel.g4

https://github.com/google/cel-go/blob/master/parser/gen/CEL.g4

Notes

CEL provides a number of runtime errors that are mapped to Python exceptions.

  • no_matching_overload: this function has no overload for the types of the arguments.

  • no_such_field: a map or message does not contain the desired field.

  • return error for overflow: integer arithmetic overflows

There are mapped to Python celpy.evaluation.EvalError exception. The args will have a message similar to the CEL error message, as well as an underlying Python exception.

In principle CEL can pre-check types. However, see https://github.com/google/cel-spec/blob/master/doc/langdef.md#gradual-type-checking. Rather than try to pre-check types, we’ll rely on Python’s implementation.

Contributing

See https://cloudcustodian.io/docs/contribute.html

Code of Conduct

This project adheres to the Open Code of Conduct. By participating, you are expected to honor this code.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cel-python-0.1.5.tar.gz (81.5 kB view details)

Uploaded Source

Built Distribution

cel_python-0.1.5-py3-none-any.whl (87.1 kB view details)

Uploaded Python 3

File details

Details for the file cel-python-0.1.5.tar.gz.

File metadata

  • Download URL: cel-python-0.1.5.tar.gz
  • Upload date:
  • Size: 81.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.25.1 setuptools/42.0.2.post20191203 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.7.5

File hashes

Hashes for cel-python-0.1.5.tar.gz
Algorithm Hash digest
SHA256 d3911bb046bc3ed12792bd88ab453f72d98c66923b72a2fa016bcdffd96e2f98
MD5 312aac2fc7da61804f63e93ddec15f62
BLAKE2b-256 b39ec3af4a83cbe8108cff92b0588b7ac53efc41fcaf1ffd09d07dc68c9b5d27

See more details on using hashes here.

File details

Details for the file cel_python-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: cel_python-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 87.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.25.1 setuptools/42.0.2.post20191203 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.7.5

File hashes

Hashes for cel_python-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 ac81fab8ba08b633700a45d84905be2863529c6a32935c9da7ef53fc06844f1a
MD5 271538cb0488157322aa75b7dbf09283
BLAKE2b-256 4e6be12b1d5593cbf49d52028bd5ace95ec3e4197365b19ea4ed198c7c06f495

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page