Skip to main content

Python interface for the OPA Rego Language and Runtime

Project description

regopy

Rego is the native query language of the Open Policy Agent project. If you want to learn more about Rego as a language, and its various use cases, we refer you to the language documentation above which OPA provides.

This module is a wrapper around rego-cpp, an open source cross-platform C++ implementation of the Rego language compiler and runtime developed and maintained by Microsoft. You can learn more about that project here. As much as possible in this wrapper we try to provide idiomatic Python interfaces to the Rego query engine. We hope the project is of use to those wishing to leverage the power of Rego within a Python context.

Warning While this project has progressed to the point that we support full Rego language (see Language Support below) we do not support all built-ins. That said, we have verified compliance with the OPA Rego test suite. Even so, it should still be considered experimental software and used with discretion.

Example Usage

from regopy import Interpreter
rego = Interpreter()
print(rego.query("x=5;y=x + (2 - 4 * 0.25) * -3 + 7.4"))
# x = 5
# y = 9.4
input0 = {
    "a": 10,
    "b": "20",
    "c": 30.0,
    "d": True
}
data0 = {
    "one": {
        "bar": "Foo",
        "baz": 5,
        "be": True,
        "bop": 23.4
    },
    "two": {
        "bar": "Bar",
        "baz": 12.3,
        "be": False,
        "bop": 42
    }
}
data1 = {
    "three": {
        "bar": "Baz",
        "baz": 15,
        "be": True,
        "bop": 4.23
    }
}
module = '''
    package objects

    rect := {`width`: 2, "height": 4}
    cube := {"width": 3, `height`: 4, "depth": 5}
    a := 42
    b := false
    c := null
    d := {"a": a, "x": [b, c]}
    index := 1
    shapes := [rect, cube]
    names := ["prod", `smoke1`, "dev"]
    sites := [{"name": "prod"}, {"name": names[index]}, {"name": "dev"}]
    e := {
        a: "foo",
        "three": c,
        names[2]: b,
        "four": d,
    }
    f := e["dev"]
'''
rego.set_input(input)
rego.add_data(data0)
rego.add_data(data1)
rego.add_module("objects", module)
print(rego.query("x=[data.one, input.b, data.objects.sites[1]]"))
# x = [{"bar":"Foo", "baz":5, "be":true, "bop":23.4}, "20", {"name":"smoke1"}]

Language Support

At present we support v0.55.0 of Rego as defined by OPA, with the following grammar:

module          = package { import } policy
package         = "package" ref
import          = "import" ref [ "as" var ]
policy          = { rule }
rule            = [ "default" ] rule-head { rule-body }
rule-head       = ( ref | var ) ( rule-head-set | rule-head-obj | rule-head-func | rule-head-comp )
rule-head-comp  = [ assign-operator term ] [ "if" ]
rule-head-obj   = "[" term "]" [ assign-operator term ] [ "if" ]
rule-head-func  = "(" rule-args ")" [ assign-operator term ] [ "if" ]
rule-head-set   = "contains" term [ "if" ] | "[" term "]"
rule-args       = term { "," term }
rule-body       = [ "else" [ assign-operator term ] [ "if" ] ] ( "{" query "}" ) | literal
query           = literal { ( ";" | ( [CR] LF ) ) literal }
literal         = ( some-decl | expr | "not" expr ) { with-modifier }
with-modifier   = "with" term "as" term
some-decl       = "some" term { "," term } { "in" expr }
expr            = term | expr-call | expr-infix | expr-every | expr-parens | unary-expr
expr-call       = var [ "." var ] "(" [ expr { "," expr } ] ")"
expr-infix      = expr infix-operator expr
expr-every      = "every" var { "," var } "in" ( term | expr-call | expr-infix ) "{" query "}"
expr-parens     = "(" expr ")"
unary-expr      = "-" expr
membership      = term [ "," term ] "in" term
term            = ref | var | scalar | array | object | set | membership | array-compr | object-compr | set-compr
array-compr     = "[" term "|" query "]"
set-compr       = "{" term "|" query "}"
object-compr    = "{" object-item "|" query "}"
infix-operator  = assign-operator | bool-operator | arith-operator | bin-operator
bool-operator   = "==" | "!=" | "<" | ">" | ">=" | "<="
arith-operator  = "+" | "-" | "*" | "/"
bin-operator    = "&" | "|"
assign-operator = ":=" | "="
ref             = ( var | array | object | set | array-compr | object-compr | set-compr | expr-call ) { ref-arg }
ref-arg         = ref-arg-dot | ref-arg-brack
ref-arg-brack   = "[" ( scalar | var | array | object | set | "_" ) "]"
ref-arg-dot     = "." var
var             = ( ALPHA | "_" ) { ALPHA | DIGIT | "_" }
scalar          = string | NUMBER | TRUE | FALSE | NULL
string          = STRING | raw-string
raw-string      = "`" { CHAR-"`" } "`"
array           = "[" term { "," term } "]"
object          = "{" object-item { "," object-item } "}"
object-item     = ( scalar | ref | var ) ":" term
set             = empty-set | non-empty-set
non-empty-set   = "{" term { "," term } "}"
empty-set       = "set(" ")"

Definitions:

[]     optional (zero or one instances)
{}     repetition (zero or more instances)
|      alternation (one of the instances)
()     grouping (order of expansion)
STRING JSON string
NUMBER JSON number
TRUE   JSON true
FALSE  JSON false
NULL   JSON null
CHAR   Unicode character
ALPHA  ASCII characters A-Z and a-z
DIGIT  ASCII characters 0-9
CR     Carriage Return
LF     Line Feed

Builtins

At the moment only support a few builtins, but are actively working on adding all the standard builtins. The following builtins are currently supported:

  • aggregates
  • arrays
  • bits
  • casts
  • numbers
  • objects
  • regex
  • semver
  • sets
  • strings
  • types
  • units
  • miscellaneous
    • base64_encode
    • base64_decode
    • json.marshal
    • opa.runtime
    • print
    • time.now_ns

Compatibility with the OPA Rego Go implementation

Our goal is to achieve and maintain full compatibility with the reference Go implementation. We have developed a test driver which runs the same tests and validates that we produce the same outputs. At this stage we pass all the non-builtin specific test suites, which we clone from the OPA repository. To build with the OPA tests available for testing, use one of the following presets:

  • release-clang-opa
  • release-opa

At present, we are NOT passing the following test suites in full:

  • base64*
  • crypto*
  • glob*
  • graphql
  • invalidkeyerror
  • json*
  • jwt*
  • net*
  • planner-ir
  • providers-aws
  • reachable
  • urlbuiltins
  • walkbuiltin

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

regopy-0.3.11.tar.gz (15.1 kB view hashes)

Uploaded Source

Built Distributions

regopy-0.3.11-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.8 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

regopy-0.3.11-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ i686

regopy-0.3.11-pp310-pypy310_pp73-macosx_10_15_x86_64.whl (6.8 MB view hashes)

Uploaded PyPy macOS 10.15+ x86-64

regopy-0.3.11-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.8 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

regopy-0.3.11-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view hashes)

Uploaded PyPy manylinux: glibc 2.17+ i686

regopy-0.3.11-pp39-pypy39_pp73-macosx_10_15_x86_64.whl (6.8 MB view hashes)

Uploaded PyPy macOS 10.15+ x86-64

regopy-0.3.11-cp312-cp312-win_amd64.whl (1.1 MB view hashes)

Uploaded CPython 3.12 Windows x86-64

regopy-0.3.11-cp312-cp312-win32.whl (936.3 kB view hashes)

Uploaded CPython 3.12 Windows x86

regopy-0.3.11-cp312-cp312-musllinux_1_1_x86_64.whl (5.9 MB view hashes)

Uploaded CPython 3.12 musllinux: musl 1.1+ x86-64

regopy-0.3.11-cp312-cp312-musllinux_1_1_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.12 musllinux: musl 1.1+ i686

regopy-0.3.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.8 MB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

regopy-0.3.11-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.12 manylinux: glibc 2.17+ i686

regopy-0.3.11-cp312-cp312-macosx_11_0_arm64.whl (7.4 MB view hashes)

Uploaded CPython 3.12 macOS 11.0+ ARM64

regopy-0.3.11-cp312-cp312-macosx_10_15_x86_64.whl (6.8 MB view hashes)

Uploaded CPython 3.12 macOS 10.15+ x86-64

regopy-0.3.11-cp311-cp311-win_amd64.whl (1.1 MB view hashes)

Uploaded CPython 3.11 Windows x86-64

regopy-0.3.11-cp311-cp311-win32.whl (936.5 kB view hashes)

Uploaded CPython 3.11 Windows x86

regopy-0.3.11-cp311-cp311-musllinux_1_1_x86_64.whl (5.9 MB view hashes)

Uploaded CPython 3.11 musllinux: musl 1.1+ x86-64

regopy-0.3.11-cp311-cp311-musllinux_1_1_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.11 musllinux: musl 1.1+ i686

regopy-0.3.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.8 MB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

regopy-0.3.11-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.11 manylinux: glibc 2.17+ i686

regopy-0.3.11-cp311-cp311-macosx_11_0_arm64.whl (7.4 MB view hashes)

Uploaded CPython 3.11 macOS 11.0+ ARM64

regopy-0.3.11-cp311-cp311-macosx_10_15_x86_64.whl (6.8 MB view hashes)

Uploaded CPython 3.11 macOS 10.15+ x86-64

regopy-0.3.11-cp310-cp310-win_amd64.whl (1.1 MB view hashes)

Uploaded CPython 3.10 Windows x86-64

regopy-0.3.11-cp310-cp310-win32.whl (935.7 kB view hashes)

Uploaded CPython 3.10 Windows x86

regopy-0.3.11-cp310-cp310-musllinux_1_1_x86_64.whl (5.9 MB view hashes)

Uploaded CPython 3.10 musllinux: musl 1.1+ x86-64

regopy-0.3.11-cp310-cp310-musllinux_1_1_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.10 musllinux: musl 1.1+ i686

regopy-0.3.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.8 MB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

regopy-0.3.11-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.10 manylinux: glibc 2.17+ i686

regopy-0.3.11-cp310-cp310-macosx_11_0_arm64.whl (7.4 MB view hashes)

Uploaded CPython 3.10 macOS 11.0+ ARM64

regopy-0.3.11-cp310-cp310-macosx_10_15_x86_64.whl (6.8 MB view hashes)

Uploaded CPython 3.10 macOS 10.15+ x86-64

regopy-0.3.11-cp39-cp39-win_amd64.whl (1.1 MB view hashes)

Uploaded CPython 3.9 Windows x86-64

regopy-0.3.11-cp39-cp39-win32.whl (935.7 kB view hashes)

Uploaded CPython 3.9 Windows x86

regopy-0.3.11-cp39-cp39-musllinux_1_1_x86_64.whl (5.9 MB view hashes)

Uploaded CPython 3.9 musllinux: musl 1.1+ x86-64

regopy-0.3.11-cp39-cp39-musllinux_1_1_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.9 musllinux: musl 1.1+ i686

regopy-0.3.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.8 MB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

regopy-0.3.11-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.9 manylinux: glibc 2.17+ i686

regopy-0.3.11-cp39-cp39-macosx_10_15_x86_64.whl (6.8 MB view hashes)

Uploaded CPython 3.9 macOS 10.15+ x86-64

regopy-0.3.11-cp38-cp38-win_amd64.whl (1.1 MB view hashes)

Uploaded CPython 3.8 Windows x86-64

regopy-0.3.11-cp38-cp38-win32.whl (935.6 kB view hashes)

Uploaded CPython 3.8 Windows x86

regopy-0.3.11-cp38-cp38-musllinux_1_1_x86_64.whl (5.9 MB view hashes)

Uploaded CPython 3.8 musllinux: musl 1.1+ x86-64

regopy-0.3.11-cp38-cp38-musllinux_1_1_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.8 musllinux: musl 1.1+ i686

regopy-0.3.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.8 MB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

regopy-0.3.11-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.8 manylinux: glibc 2.17+ i686

regopy-0.3.11-cp37-cp37m-win_amd64.whl (1.1 MB view hashes)

Uploaded CPython 3.7m Windows x86-64

regopy-0.3.11-cp37-cp37m-win32.whl (936.2 kB view hashes)

Uploaded CPython 3.7m Windows x86

regopy-0.3.11-cp37-cp37m-musllinux_1_1_x86_64.whl (5.9 MB view hashes)

Uploaded CPython 3.7m musllinux: musl 1.1+ x86-64

regopy-0.3.11-cp37-cp37m-musllinux_1_1_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.7m musllinux: musl 1.1+ i686

regopy-0.3.11-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.8 MB view hashes)

Uploaded CPython 3.7m manylinux: glibc 2.17+ x86-64

regopy-0.3.11-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl (6.3 MB view hashes)

Uploaded CPython 3.7m manylinux: glibc 2.17+ i686

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