Skip to main content

The CEL Python runtime

Project description

CEL Python Wrapper (cel-expr-python)

This is a Python wrapper for the CEL C++ implementation.

Usage

Importing CEL module

from cel_expr_python import cel

Creating and configuring CEL environment

To create a CEL environment, you need to define variable types that can be used in expressions.

cel_env = cel.NewEnv(variables={"x": cel.Type.INT, "y": cel.Type.INT})

Optional configuration parameters

The cel.NewEnv constructor also accepts the following optional parameters:

  • pool (descriptor_pool.DescriptorPool): The descriptor pool used for resolving protobuf message types within CEL expressions. If not provided, a default pool (descriptor_pool.Default()) is used.

  • container (str or cel.ExpressionContainer): The container name used for name resolution. For example, if container is "foo.bar", then Baz will resolve to foo.bar.Baz.

    You can also pass a cel.ExpressionContainer to configure abbreviations and aliases:

    container = cel.ExpressionContainer(
        name="foo.bar",
        abbreviations=["foo.bar.baz"],
        aliases={"my_alias": "full.name.of.something"}
    )
    cel_env = cel.NewEnv(container=container)
    
    • abbreviations: A list of fully qualified names that can be referred to by their last component.
    • aliases: A dictionary mapping an alias name to a fully qualified name.
  • extensions (list): A list of extension objects to load. This can include standard extensions (like math or string libraries) or custom extensions defined in Python or C++.

Compiling expressions

Use the compile() method to compile a CEL expression string into a reusable expression object.

expr = cel_env.compile("x + y > 10")

The expr object can be serialized into a binary format for persistence and later deserialized.

serialized_expr = expr.serialize()
# ... can be stored or sent over network ...
deserialized_expr = cel_env.deserialize(serialized_expr)

The compile method can take an optional disable_check=True argument, which disables type checking until runtime. This could be useful when types of variables are not known at compile time.

Evaluation

To evaluate a compiled expression, you need to provide bindings for variables and then call eval().

you need to create an activation, which provides bindings for variables, and then call eval().

# Provide variable values in a dictionary and evaluate the expression.
result = expr.eval(data={"x": 7, "y": 4})

# The result is a `CelValue` object, which contains the result's CEL type and
# value.

# Get the result value.
print(f"Result type: {result.type()}")
print(f"Result value: {result.value()}")

This will output:

Result type: BOOL
Result value: True

Using an Activation

The eval() function can also be invoked with an Activation object that holds variable bindings and a pointer to an Arena (see below). This is particularly useful when multiple expressions need to be evaluated with the same set of variable values, such as multiple policies on the same server request.

expr1 = cel_env.compile("user.role in ['admin', 'owner']")
expr2 = cel_env.compile("user.organization == 'myorg'")

# Provide variable values as an Activation.
activation = cel_env.Activation({"user": user})

# Evaluate the expression.
result1 = expr1.eval(activation)

# Evaluate another expression using the same variable bindings
result2 = expr2.eval(activation)

Using an Arena

The eval() function as well as an Activation can also take an Arena for memory management during evaluation. This is a memory optimization technique that allows temporary C++ objects created during the evaluation to be released as a group. The same Arena can be shared across multiple activations; just keep in mind that none of the associated objects are released until the last object using the arena is garbage-collected in Python.

arena = cel.Arena()

activation1 = cel_env.Activation({"x": 7, "y": 4}, arena)
# evaluate some expressions
activation2 = cel_env.Activation({"x": 8, "y": 9}, arena)
# evaluate some more expressions

# Process all results. Note: Don't put CelValues in long-lived data structures
# if you want the arena to be garbage-collected promptly.

# When `arena` and all `CelValue` objects produced with it go out of scope,
# all memory allocated for C++ objects during evaluation will be released.

Working with Protobufs

You can pass protobuf messages as variables to an activation; CEL expressions can return protobuf messages.

First, ensure your proto messages are available in the descriptor pool used by cel.NewEnv, by importing your proto library in Python:

from cel.expr.conformance.proto2 import test_all_types_pb2 as test_pb

Then declare any variables of message type using cel.Type with their fully qualified name.

# Declare 'msg_var' as a message type.
cel = cel.NewEnv(
    pool,
    variables={
        "msg_var": cel.Type("cel.expr.conformance.proto2.TestAllTypes"),
    },
)

Compile an expression that uses message fields:

expr = cel.compile("msg_var.single_int32 == 42")

Pass a message in the activation. When passing a message to an activation, use an instance of the Python proto message class.

my_msg = test_pb.TestAllTypes(single_int32=42)

activation = cel_env.Activation({"msg_var": my_msg})
result = expr.eval(activation)
print(f"Result: {result.value()}")

An expression can also return a proto message:

msg_expr = cel_env.compile(
    "cel.expr.conformance.proto2.TestAllTypes{single_int32: 123}"
)
msg_result = msg_expr.eval(activation)
proto_val = msg_result.value()
print(f"Resulting message type: {type(proto_val)}")
print(f"Resulting message value: {proto_val.single_int32}")

This will output:

Resulting message type: <class '...TestAllTypes'>
Resulting message value: 123

Custom functions

When configuring cel.Env you can supply custom functions. For each function there needs to be a declaration and an implementation. The implementation, which is a Python function, can be provided either as part of the declaration or separately.

Let's say we want to be able to invoke this function from CEL expressions:

  def good_time_of_day(ampm, arg):
    if ampm == 'am':
      time_of_day = 'morning'
    else:
      time_of_day = 'afternoon'
    return f"Good {time_of_day}, {arg}"

The implementation can be supplied along with the declaration:

  cel_env = cel.NewEnv(functions=[
            cel.FunctionDecl(
                "hello",
                [
                    cel.Overload(
                        "hello(string,string)",
                        return_type=cel.Type.STRING,
                        parameters=[
                            cel.Type.STRING,
                            cel.Type.STRING,
                        ],
                        impl=good_time_of_day,
                    )
                ],
            )
        ])

It can also be provided separately in a dictionary that maps overload IDs to their respective implementations:

  cel_env = cel.NewEnv(functions=[
            cel.FunctionDecl(
                "hello",
                [
                    cel.Overload(
                        "hello(string,string)",
                        return_type=cel.Type.STRING,
                        parameters=[
                            cel.Type.STRING,
                            cel.Type.STRING,
                        ],
                    )
                ],
            )
        ],
        function_impls={
            "hello(string,string)": good_time_of_day,
        })

Now that the function implementation is bound to the CEL environment, we can invoke it from CEL like this:

    result = env.compile("hello('am', 'breakfast is ready!')").eval()
    print(result.value())   # Good morning, breakfast is ready!
    result = env.compile("hello('pm', 'tea is served.')").eval()
    print(result.value())   # Good afternoon, tea is served.

Extensions

Standard extensions

Standard extensions are available under cel_expr_python.ext.

from cel_expr_python.ext import ext_math

env = cel.NewEnv(pool, extensions=[ext_math.ExtMath()])
expr = env.compile("math.sqrt(4)")

Defining a custom extension in Python

You can define custom functions and pass them as an extension.

def my_func_impl(x):
  return x + 1

my_ext = cel.CelExtension(
    "my_extension",
    [
        cel.FunctionDecl(
            "my_func",
            [
                cel.Overload(
                    "my_func_int",
                    cel.Type.INT,
                    [cel.Type.INT],
                    impl=my_func_impl,
                )
            ],
        )
    ],
)

cel_env = cel.NewEnv(pool, extensions=[my_ext])
expr = cel_env.compile("my_func(1)")

Defining a custom extension in C++

To define a custom extension in C++, define a class extending cel_python::CelExtension. There are two methods you will need to implement: GetCompilerLibrary and ConfigureRuntime. The implementations of these methods use the same API as extensions written for the C++ CEL runtime. In fact, extensions written for the C++ runtime can be used unchanged with cel-expr-python - you would just need to write a trivial wrapper class invoking the registration functions defined by the C++ extension.

This method adds extension function definitions to the provided CompilerBuilder, for example:

  cel::CompilerLibrary GetCompilerLibrary() {
    return cel::CompilerLibrary(
        "translate-ext",
        [](cel::TypeCheckerBuilder& checker_builder) -> absl::Status {
          CEL_PYTHON_ASSIGN_OR_RETURN(
              auto func_translate,
              cel::MakeFunctionDecl(
                  "translate",
                  cel::MakeMemberOverloadDecl("translate_inst",
                                              /*return_type=*/cel::StringType(),
                                              /*target=*/cel::StringType(),
                                              /*from_lang=*/cel::StringType(),
                                              /*to_lang=*/cel::StringType())));
          CEL_PYTHON_RETURN_IF_ERROR(
              checker_builder.AddFunction(func_translate));
          return absl::OkStatus();
        });
  }

The other method registers the actual implementation of the extension function with the runtime:

absl::Status ConfigureRuntime(cel::RuntimeBuilder& runtime_builder,
                              const cel::RuntimeOptions& opts);

For example,

static absl::StatusOr<cel::StringValue> Translate(
    const cel::StringValue& text, const cel::StringValue& from_lang,
    const cel::StringValue& to_lang, const proto2::DescriptorPool* absl_nonnull,
    proto2::MessageFactory* absl_nonnull, proto2::Arena* absl_nonnull arena) {
  return cel::StringValue::From("¡Hola Mundo!", arena);
}

absl::Status ConfigureRuntime(cel::RuntimeBuilder& runtime_builder,
                                const cel::RuntimeOptions& opts) override {
    using TranslateFunctionAdapter =
        cel::TernaryFunctionAdapter<absl::StatusOr<StringValue>,
                                      const StringValue&, const StringValue&,
                                      const StringValue&>;
    auto status = TranslateFunctionAdapter::RegisterMemberOverload(
        "translate", &Translate, runtime_builder.function_registry());
    CEL_PYTHON_RETURN_IF_ERROR(status);
    return absl::OkStatus();
}

Once you have the custom subclass of cel_python::CelExtension, add this line to turn this class into a Python module:

CEL_EXTENSION_MODULE(translation_cel_ext, TranslationCelExtension);

To build the Python module, use the pybind_extension BUILD rule:

pybind_extension(
    name = "translation_cel_ext",
    srcs = ["translation_cel_ext.cc"],
    data = [
        "@cel_expr_python:cel",
    ]
    deps = [
        "@cel_expr_python:cel",
        "@cel_expr_python:cel_extension",
        "@cel_expr_python:status_macros",
        ...
    ],
)

Now you can use the extension in cel_expr_python:

import translation_cel_ext

cel_env = cel.NewEnv(variables={},
  extensions=[translation_cel_ext.TranslationCelExtension()])

expr = cel_env.compile("'Hello, world!'.translate('en', 'es')")

Late-bound extension functions

Sometimes it is required to delay the binding of an extension function implementation until the runtime. To do this in an extension written in Python, simply leave the implementation parameter unspecified:

my_ext = cel.CelExtension(
    "my_extension",
    [
        cel.FunctionDecl(
            "my_func",
            [
                cel.Overload(
                    "my_func_int",
                    cel.Type.INT,
                    [cel.Type.INT],
                    # Note: no impl provided here.
                )
            ],
        )
    ],
)

If the extension is written in C++, use the RegisterLazyFunction function:

  absl::Status ConfigureRuntime(cel::RuntimeBuilder& runtime_builder,
                                const cel::RuntimeOptions& opts) override {
    using MyFunctionAdapter =
        cel::UnaryFunctionAdapter<absl::StatusOr<cel::IntValue>,
                                    const cel::IntValue&>;
    CEL_PYTHON_RETURN_IF_ERROR(
        runtime_builder.function_registry().RegisterLazyFunction(
            MyFunctionAdapter::CreateDescriptor(
                "my_func",
                /*receiver_style=*/false)));
    return absl::OkStatus();
  }

Now you can bind the function at runtime:

cel_env = cel.NewEnv(variables={}, extensions=[my_ext])
expr = cel_env.compile("my_func(42)")

multiplier = 2
act = cel_env.Activation({}, functions={"my_func": lambda x: x * multiplier})
res = expr.eval(act)
# res.value() == 84

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

cel_expr_python-0.1.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (17.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

cel_expr_python-0.1.2-cp314-cp314-macosx_11_0_arm64.whl (11.8 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

cel_expr_python-0.1.2-cp313-cp313-win_amd64.whl (13.2 MB view details)

Uploaded CPython 3.13Windows x86-64

cel_expr_python-0.1.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (17.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

cel_expr_python-0.1.2-cp313-cp313-macosx_11_0_arm64.whl (11.8 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

cel_expr_python-0.1.2-cp312-cp312-win_amd64.whl (14.5 MB view details)

Uploaded CPython 3.12Windows x86-64

cel_expr_python-0.1.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (17.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

cel_expr_python-0.1.2-cp312-cp312-macosx_11_0_arm64.whl (11.8 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

cel_expr_python-0.1.2-cp311-cp311-win_amd64.whl (7.5 MB view details)

Uploaded CPython 3.11Windows x86-64

cel_expr_python-0.1.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (15.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

cel_expr_python-0.1.2-cp311-cp311-macosx_11_0_arm64.whl (11.8 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

Details for the file cel_expr_python-0.1.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 bf8f571da3cee607e9df8a4733efd32bf479d20d5bfdabc13913076119485bc9
MD5 f33a1849d4cf1f55f37ef6870574f70d
BLAKE2b-256 72e61fc92ee93c0ff77033358b05fab242227427bbbcd37553ad7277957c6c5f

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

File details

Details for the file cel_expr_python-0.1.2-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8f431b5f3806710d0c6eeeba79a0b6268f63995fcaa62f85273f2906621894d7
MD5 60c61f357ce0c5edb617d497cf791f06
BLAKE2b-256 e58ea972241000dc24364aa3c4f79ea8c27810f8f23d52913dab212b9533d207

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

File details

Details for the file cel_expr_python-0.1.2-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 1fc95a2bfe6d1f9d643a67b65a46f7dadd8f4da73aa7c51b59821c23e648001b
MD5 0b426c00b23b9933b7f9112fb2dce752
BLAKE2b-256 3c48130a95394dd682dc28ac8b9a2db5e8d33cf8feaa56abcd90b7d95f447065

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp313-cp313-win_amd64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

File details

Details for the file cel_expr_python-0.1.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6fb2d134468317eefaed035560a07a7e783db7df256777efbae8236e96b3f6e8
MD5 3af8b3ecef55726512093de49014698b
BLAKE2b-256 8f2420c381d663f53bb7283e47da091afbe7f6e7e3add39fc14aa748a767b011

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

File details

Details for the file cel_expr_python-0.1.2-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a6c4e4218a4b18cc54c061f3bfc53f4cbac2ca8ae43a0c2fb2fdaa07cb7dae4d
MD5 64d6cbd1efecacfcc01c43e17a7a0be6
BLAKE2b-256 597975d0897dd2c3c9f20376ae7a369de7b528ba7064632621463f920ad52517

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

File details

Details for the file cel_expr_python-0.1.2-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 d7b1acd64c8150ddc7bf33dbb5e9761643d6783b59d0b05b96259c327de58297
MD5 93d1e81f36d77fb6cdc8b8e8d7e4a155
BLAKE2b-256 edd61c50a96289c52ca577910e7eca482b12f79a4ac2847ad7a9fccb22ff7be8

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp312-cp312-win_amd64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

File details

Details for the file cel_expr_python-0.1.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 671b230b2fefdc621d5038ae7d9ccff651c12a9913137b03a6cf78556fba0f94
MD5 ccd32e7ed89efb170b35f5958eb5dead
BLAKE2b-256 87121309c203a38c573549a393475fb9a503b543f551618f59a74a4632a0a544

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

File details

Details for the file cel_expr_python-0.1.2-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d98c2b821c921e41965c54688fe23bef26742f0a138a75e3928359bd2090b183
MD5 65da09715c7e6077ecb6d853ab228c8d
BLAKE2b-256 9fbb3a9f008001e86a4995d5e68785d0afc78debee9d69faf97b11bd3135a9f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

File details

Details for the file cel_expr_python-0.1.2-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 5509ea5b6d9f34c213a21a5974d865298274a8b214fcb828232846dd8ec3116e
MD5 b58e463166c82dad2855718982c9bf69
BLAKE2b-256 0331ff89b8ea544e2159498c9e30a9712278b00ba8ea498f88d0c8d3ffe4f81b

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp311-cp311-win_amd64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

File details

Details for the file cel_expr_python-0.1.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b56d6715ff1c011b7059e2b7fed462e34e5926f3de25e76b7298c74623813322
MD5 cb492b429e034fa5ddf41444acb2c359
BLAKE2b-256 ce01a1f30887dbdc839e9dfe0af0a8d2f2bc37bbd4d4216bab1ef4567f6ff4eb

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

File details

Details for the file cel_expr_python-0.1.2-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cel_expr_python-0.1.2-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c25f340e2e2f60949c63d4a951ae6c4800dce570f7ee2ae4f8832b0de14639de
MD5 26ad3f3c6aa7388c0a8af245a0e6f0c5
BLAKE2b-256 5022c0e631949f25b2f664d0391d1f8e67662538d58fa10cb0cd2452adfee76a

See more details on using hashes here.

Provenance

The following attestation bundles were made for cel_expr_python-0.1.2-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
  • Statement: Publication detail:
    • Token Issuer: https://accounts.google.com
    • Service Account: cel-expr-python-py@oss-exit-gate-prod.iam.gserviceaccount.com

Supported by

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