mirror of https://github.com/nucypher/nucypher.git
respond to RFCs in PR #3511
parent
f59d636d54
commit
f2c7337483
113
Pipfile
113
Pipfile
|
@ -1,113 +0,0 @@
|
||||||
[[source]]
|
|
||||||
url = "https://pypi.org/simple"
|
|
||||||
verify_ssl = true
|
|
||||||
name = "pypi"
|
|
||||||
|
|
||||||
[packages]
|
|
||||||
abnf = "==1.1.1"
|
|
||||||
aiohttp = "==3.9.4rc0"
|
|
||||||
aiosignal = "==1.3.1"
|
|
||||||
annotated-types = "==0.6.0"
|
|
||||||
appdirs = "==1.4.4"
|
|
||||||
async-timeout = "==4.0.3"
|
|
||||||
attrs = "==23.2.0"
|
|
||||||
atxm = "==0.3.0"
|
|
||||||
autobahn = "==23.1.2"
|
|
||||||
automat = "==22.10.0"
|
|
||||||
backports-zoneinfo = "==0.2.1"
|
|
||||||
bitarray = "==2.9.2"
|
|
||||||
blinker = "==1.8.2"
|
|
||||||
bytestring-splitter = "==2.4.1"
|
|
||||||
certifi = "==2024.2.2"
|
|
||||||
cffi = "==1.16.0"
|
|
||||||
charset-normalizer = "==3.3.2"
|
|
||||||
click = "==8.1.7"
|
|
||||||
colorama = "==0.4.6"
|
|
||||||
constant-sorrow = "==0.1.0a9"
|
|
||||||
constantly = "==23.10.4"
|
|
||||||
cryptography = "==42.0.7"
|
|
||||||
cytoolz = "==0.12.3"
|
|
||||||
dateparser = "==1.2.0"
|
|
||||||
eth-abi = "==4.2.1"
|
|
||||||
eth-account = "==0.10.0"
|
|
||||||
eth-hash = {extras = ["pycryptodome"], version = "==0.7.0"}
|
|
||||||
eth-keyfile = "==0.8.0"
|
|
||||||
eth-keys = "==0.4.0"
|
|
||||||
eth-rlp = "==1.0.1"
|
|
||||||
eth-typing = "==3.5.2"
|
|
||||||
eth-utils = "==2.3.1"
|
|
||||||
flask = "==3.0.3"
|
|
||||||
frozenlist = "==1.4.1"
|
|
||||||
hendrix = "==5.0.0"
|
|
||||||
hexbytes = "==0.3.1"
|
|
||||||
humanize = "==4.9.0"
|
|
||||||
hyperlink = "==21.0.0"
|
|
||||||
idna = "==3.7"
|
|
||||||
importlib-metadata = "==7.1.0"
|
|
||||||
importlib-resources = "==6.4.0"
|
|
||||||
incremental = "==22.10.0"
|
|
||||||
itsdangerous = "==2.2.0"
|
|
||||||
jinja2 = "==3.1.4"
|
|
||||||
jsonpath-ng = "==1.6.1"
|
|
||||||
jsonschema-specifications = "==2023.12.1"
|
|
||||||
jsonschema = "==4.21.1"
|
|
||||||
lru-dict = "==1.2.0"
|
|
||||||
mako = "==1.3.5"
|
|
||||||
markupsafe = "==2.1.5"
|
|
||||||
marshmallow = "==3.21.2"
|
|
||||||
maya = "==0.6.1"
|
|
||||||
mnemonic = "==0.20"
|
|
||||||
msgpack-python = "==0.5.6"
|
|
||||||
multidict = "==6.0.5"
|
|
||||||
nucypher-core = "==0.13.0"
|
|
||||||
packaging = "==23.2"
|
|
||||||
parsimonious = "==0.9.0"
|
|
||||||
pendulum = "==3.0.0"
|
|
||||||
pkgutil-resolve-name = "==1.3.10"
|
|
||||||
prometheus-client = "==0.20.0"
|
|
||||||
protobuf = "==5.26.1"
|
|
||||||
pyasn1-modules = "==0.4.0"
|
|
||||||
pyasn1 = "==0.6.0"
|
|
||||||
pychalk = "==2.0.1"
|
|
||||||
pycparser = "==2.22"
|
|
||||||
pycryptodome = "==3.20.0"
|
|
||||||
pydantic-core = "==2.18.2"
|
|
||||||
pydantic = "==2.7.1"
|
|
||||||
pynacl = "==1.5.0"
|
|
||||||
pyopenssl = "==24.1.0"
|
|
||||||
python-dateutil = "==2.8.2"
|
|
||||||
python-statemachine = "==2.1.2"
|
|
||||||
pytz = "==2024.1"
|
|
||||||
pyunormalize = "==15.1.0"
|
|
||||||
pywin32 = "==306"
|
|
||||||
referencing = "==0.34.0"
|
|
||||||
regex = "==2023.12.25"
|
|
||||||
requests = "==2.31.0"
|
|
||||||
rlp = "==3.0.0"
|
|
||||||
rpds-py = "==0.18.0"
|
|
||||||
service-identity = "==24.1.0"
|
|
||||||
siwe = "==2.4.1"
|
|
||||||
six = "==1.16.0"
|
|
||||||
snaptime = "==0.2.4"
|
|
||||||
tabulate = "==0.9.0"
|
|
||||||
time-machine = "==2.14.1"
|
|
||||||
toolz = "==0.12.1"
|
|
||||||
twisted-iocpsupport = "==1.0.4"
|
|
||||||
twisted = "==24.3.0"
|
|
||||||
txaio = "==23.1.1"
|
|
||||||
typing-extensions = "==4.11.0"
|
|
||||||
tzdata = "==2024.1"
|
|
||||||
tzlocal = "==5.2"
|
|
||||||
urllib3 = "==2.2.0"
|
|
||||||
watchdog = "==3.0.0"
|
|
||||||
web3 = "==6.15.1"
|
|
||||||
websockets = "==12.0"
|
|
||||||
werkzeug = "==3.0.3"
|
|
||||||
yarl = "==1.9.4"
|
|
||||||
zipp = "==3.18.1"
|
|
||||||
zope-interface = "==6.2"
|
|
||||||
|
|
||||||
[dev-packages]
|
|
||||||
|
|
||||||
[requires]
|
|
||||||
python_version = "3.12"
|
|
|
@ -73,8 +73,8 @@ class ConditionType(Enum):
|
||||||
TIME = "time"
|
TIME = "time"
|
||||||
CONTRACT = "contract"
|
CONTRACT = "contract"
|
||||||
RPC = "rpc"
|
RPC = "rpc"
|
||||||
|
JSONAPI = "json-api"
|
||||||
COMPOUND = "compound"
|
COMPOUND = "compound"
|
||||||
OFFCHAIN = "offchain"
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def values(cls) -> List[str]:
|
def values(cls) -> List[str]:
|
||||||
|
@ -417,7 +417,7 @@ class ConditionLingo(_Serializable):
|
||||||
conditions expression framework.
|
conditions expression framework.
|
||||||
"""
|
"""
|
||||||
from nucypher.policy.conditions.evm import ContractCondition, RPCCondition
|
from nucypher.policy.conditions.evm import ContractCondition, RPCCondition
|
||||||
from nucypher.policy.conditions.offchain import OffchainCondition
|
from nucypher.policy.conditions.offchain import JsonApiCondition
|
||||||
from nucypher.policy.conditions.time import TimeCondition
|
from nucypher.policy.conditions.time import TimeCondition
|
||||||
|
|
||||||
# version logical adjustments can be made here as required
|
# version logical adjustments can be made here as required
|
||||||
|
@ -428,7 +428,7 @@ class ConditionLingo(_Serializable):
|
||||||
ContractCondition,
|
ContractCondition,
|
||||||
RPCCondition,
|
RPCCondition,
|
||||||
CompoundAccessControlCondition,
|
CompoundAccessControlCondition,
|
||||||
OffchainCondition,
|
JsonApiCondition,
|
||||||
):
|
):
|
||||||
if condition.CONDITION_TYPE == condition_type:
|
if condition.CONDITION_TYPE == condition_type:
|
||||||
return condition
|
return condition
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import Any, Optional, Tuple
|
||||||
import requests
|
import requests
|
||||||
from jsonpath_ng.exceptions import JsonPathLexerError, JsonPathParserError
|
from jsonpath_ng.exceptions import JsonPathLexerError, JsonPathParserError
|
||||||
from jsonpath_ng.ext import parse
|
from jsonpath_ng.ext import parse
|
||||||
from marshmallow import ValidationError, fields, post_load, validate
|
from marshmallow import fields, post_load, validate
|
||||||
from marshmallow.fields import Field
|
from marshmallow.fields import Field
|
||||||
|
|
||||||
from nucypher.policy.conditions.base import AccessControlCondition
|
from nucypher.policy.conditions.base import AccessControlCondition
|
||||||
|
@ -17,33 +17,36 @@ from nucypher.utilities.logging import Logger
|
||||||
|
|
||||||
|
|
||||||
class JSONPathField(Field):
|
class JSONPathField(Field):
|
||||||
default_error_messages = {"invalid": "Not a valid JSONPath expression."}
|
default_error_messages = {
|
||||||
|
"invalidType": "Expression of type '{type(value)}' is not valid for JSONPath",
|
||||||
|
"invalid": "'{value}' is not a valid JSONPath expression",
|
||||||
|
}
|
||||||
|
|
||||||
def _deserialize(self, value, attr, data, **kwargs):
|
def _deserialize(self, value, attr, data, **kwargs):
|
||||||
if not isinstance(value, str):
|
if not isinstance(value, str):
|
||||||
self.fail("invalid")
|
raise self.make_error("invalidType", input=value)
|
||||||
try:
|
try:
|
||||||
parse(value)
|
parse(value)
|
||||||
except (JsonPathLexerError, JsonPathParserError):
|
except (JsonPathLexerError, JsonPathParserError):
|
||||||
self.fail("invalid")
|
raise self.make_error("invalid", value=value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
class OffchainCondition(AccessControlCondition):
|
class JsonApiCondition(AccessControlCondition):
|
||||||
"""
|
"""
|
||||||
An offchain condition is a condition that can be evaluated by reading from a JSON
|
A JSON API condition is a condition that can be evaluated by reading from a JSON
|
||||||
endpoint. This may be a REST service but the only requirement is that
|
HTTPS endpoint. The response must return an HTTP 200 with valid JSON in the response body.
|
||||||
the response is JSON and can be parsed using jsonpath.
|
The response will be deserialized as JSON and parsed using jsonpath.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
CONDITION_TYPE = ConditionType.OFFCHAIN.value
|
CONDITION_TYPE = ConditionType.JSONAPI.value
|
||||||
LOGGER = Logger("nucypher.policy.conditions.offchain")
|
LOGGER = Logger("nucypher.policy.conditions.JsonApiCondition")
|
||||||
|
|
||||||
class Schema(CamelCaseSchema):
|
class Schema(CamelCaseSchema):
|
||||||
|
|
||||||
name = fields.Str(required=False)
|
name = fields.Str(required=False)
|
||||||
condition_type = fields.Str(
|
condition_type = fields.Str(
|
||||||
validate=validate.Equal(ConditionType.OFFCHAIN.value), required=True
|
validate=validate.Equal(ConditionType.JSONAPI.value), required=True
|
||||||
)
|
)
|
||||||
headers = fields.Dict(required=False)
|
headers = fields.Dict(required=False)
|
||||||
parameters = fields.Dict(required=False)
|
parameters = fields.Dict(required=False)
|
||||||
|
@ -53,15 +56,9 @@ class OffchainCondition(AccessControlCondition):
|
||||||
ReturnValueTest.ReturnValueTestSchema(), required=True
|
ReturnValueTest.ReturnValueTestSchema(), required=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def validate_query(self, value):
|
|
||||||
try:
|
|
||||||
parse(value)
|
|
||||||
except Exception as e:
|
|
||||||
raise ValidationError(f"Invalid JSONPath query: {e}")
|
|
||||||
|
|
||||||
@post_load
|
@post_load
|
||||||
def make(self, data, **kwargs):
|
def make(self, data, **kwargs):
|
||||||
return OffchainCondition(**data)
|
return JsonApiCondition(**data)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
@ -70,7 +67,7 @@ class OffchainCondition(AccessControlCondition):
|
||||||
return_value_test: ReturnValueTest,
|
return_value_test: ReturnValueTest,
|
||||||
headers: Optional[dict] = None,
|
headers: Optional[dict] = None,
|
||||||
parameters: Optional[dict] = None,
|
parameters: Optional[dict] = None,
|
||||||
condition_type: str = ConditionType.OFFCHAIN.value,
|
condition_type: str = ConditionType.JSONAPI.value,
|
||||||
):
|
):
|
||||||
if condition_type != self.CONDITION_TYPE:
|
if condition_type != self.CONDITION_TYPE:
|
||||||
raise InvalidCondition(
|
raise InvalidCondition(
|
||||||
|
@ -102,6 +99,14 @@ class OffchainCondition(AccessControlCondition):
|
||||||
f"Failed to fetch endpoint {self.endpoint}: {request_error}"
|
f"Failed to fetch endpoint {self.endpoint}: {request_error}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
self.logger.error(
|
||||||
|
f"Failed to fetch endpoint {self.endpoint}: {response.status_code}"
|
||||||
|
)
|
||||||
|
raise ConditionEvaluationFailed(
|
||||||
|
f"Failed to fetch endpoint {self.endpoint}: {response.status_code}"
|
||||||
|
)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def deserialize_response(self, response: requests.Response) -> Any:
|
def deserialize_response(self, response: requests.Response) -> Any:
|
||||||
|
|
|
@ -9,7 +9,7 @@ from nucypher.policy.conditions.exceptions import (
|
||||||
InvalidCondition,
|
InvalidCondition,
|
||||||
)
|
)
|
||||||
from nucypher.policy.conditions.lingo import ConditionLingo, ReturnValueTest
|
from nucypher.policy.conditions.lingo import ConditionLingo, ReturnValueTest
|
||||||
from nucypher.policy.conditions.offchain import JSONPathField, OffchainCondition
|
from nucypher.policy.conditions.offchain import JsonApiCondition, JSONPathField
|
||||||
|
|
||||||
|
|
||||||
def test_jsonpath_field_valid():
|
def test_jsonpath_field_valid():
|
||||||
|
@ -24,11 +24,13 @@ def test_jsonpath_field_invalid():
|
||||||
invalid_jsonpath = "invalid jsonpath"
|
invalid_jsonpath = "invalid jsonpath"
|
||||||
with pytest.raises(ValidationError) as excinfo:
|
with pytest.raises(ValidationError) as excinfo:
|
||||||
field.deserialize(invalid_jsonpath)
|
field.deserialize(invalid_jsonpath)
|
||||||
assert "Not a valid JSONPath expression." in str(excinfo.value)
|
assert f"'{invalid_jsonpath}' is not a valid JSONPath expression" in str(
|
||||||
|
excinfo.value
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_offchain_condition_initialization():
|
def test_json_api_condition_initialization():
|
||||||
condition = OffchainCondition(
|
condition = JsonApiCondition(
|
||||||
endpoint="https://api.example.com/data",
|
endpoint="https://api.example.com/data",
|
||||||
query="$.store.book[0].price",
|
query="$.store.book[0].price",
|
||||||
return_value_test=ReturnValueTest("==", 0),
|
return_value_test=ReturnValueTest("==", 0),
|
||||||
|
@ -38,23 +40,23 @@ def test_offchain_condition_initialization():
|
||||||
assert condition.return_value_test.eval(0)
|
assert condition.return_value_test.eval(0)
|
||||||
|
|
||||||
|
|
||||||
def test_offchain_condition_invalid_type():
|
def test_json_api_condition_invalid_type():
|
||||||
with pytest.raises(InvalidCondition) as excinfo:
|
with pytest.raises(InvalidCondition) as excinfo:
|
||||||
OffchainCondition(
|
JsonApiCondition(
|
||||||
endpoint="https://api.example.com/data",
|
endpoint="https://api.example.com/data",
|
||||||
query="$.store.book[0].price",
|
query="$.store.book[0].price",
|
||||||
return_value_test=ReturnValueTest("==", 0),
|
return_value_test=ReturnValueTest("==", 0),
|
||||||
condition_type="INVALID_TYPE",
|
condition_type="INVALID_TYPE",
|
||||||
)
|
)
|
||||||
assert "must be instantiated with the offchain type" in str(excinfo.value)
|
assert "must be instantiated with the json-api type" in str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
def test_offchain_condition_fetch(mocker):
|
def test_json_api_condition_fetch(mocker):
|
||||||
mock_response = mocker.Mock(status_code=200)
|
mock_response = mocker.Mock(status_code=200)
|
||||||
mock_response.json.return_value = {"store": {"book": [{"title": "Test Title"}]}}
|
mock_response.json.return_value = {"store": {"book": [{"title": "Test Title"}]}}
|
||||||
mocker.patch("requests.get", return_value=mock_response)
|
mocker.patch("requests.get", return_value=mock_response)
|
||||||
|
|
||||||
condition = OffchainCondition(
|
condition = JsonApiCondition(
|
||||||
endpoint="https://api.example.com/data",
|
endpoint="https://api.example.com/data",
|
||||||
query="$.store.book[0].title",
|
query="$.store.book[0].title",
|
||||||
return_value_test=ReturnValueTest("==", "'Test Title'"),
|
return_value_test=ReturnValueTest("==", "'Test Title'"),
|
||||||
|
@ -64,12 +66,12 @@ def test_offchain_condition_fetch(mocker):
|
||||||
assert response.json() == {"store": {"book": [{"title": "Test Title"}]}}
|
assert response.json() == {"store": {"book": [{"title": "Test Title"}]}}
|
||||||
|
|
||||||
|
|
||||||
def test_offchain_condition_fetch_failure(mocker):
|
def test_json_api_condition_fetch_failure(mocker):
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
"requests.get", side_effect=requests.exceptions.RequestException("Error")
|
"requests.get", side_effect=requests.exceptions.RequestException("Error")
|
||||||
)
|
)
|
||||||
|
|
||||||
condition = OffchainCondition(
|
condition = JsonApiCondition(
|
||||||
endpoint="https://api.example.com/data",
|
endpoint="https://api.example.com/data",
|
||||||
query="$.store.book[0].price",
|
query="$.store.book[0].price",
|
||||||
return_value_test=ReturnValueTest("==", "1"),
|
return_value_test=ReturnValueTest("==", "1"),
|
||||||
|
@ -79,12 +81,12 @@ def test_offchain_condition_fetch_failure(mocker):
|
||||||
assert "Failed to fetch endpoint" in str(excinfo.value)
|
assert "Failed to fetch endpoint" in str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
def test_offchain_condition_verify(mocker):
|
def test_json_api_condition_verify(mocker):
|
||||||
mock_response = mocker.Mock(status_code=200)
|
mock_response = mocker.Mock(status_code=200)
|
||||||
mock_response.json.return_value = {"store": {"book": [{"price": "1"}]}}
|
mock_response.json.return_value = {"store": {"book": [{"price": "1"}]}}
|
||||||
mocker.patch("requests.get", return_value=mock_response)
|
mocker.patch("requests.get", return_value=mock_response)
|
||||||
|
|
||||||
condition = OffchainCondition(
|
condition = JsonApiCondition(
|
||||||
endpoint="https://api.example.com/data",
|
endpoint="https://api.example.com/data",
|
||||||
query="$.store.book[0].price",
|
query="$.store.book[0].price",
|
||||||
return_value_test=ReturnValueTest("==", "1"),
|
return_value_test=ReturnValueTest("==", "1"),
|
||||||
|
@ -94,12 +96,12 @@ def test_offchain_condition_verify(mocker):
|
||||||
assert value == "1"
|
assert value == "1"
|
||||||
|
|
||||||
|
|
||||||
def test_offchain_condition_verify_invalid_json(mocker):
|
def test_json_api_condition_verify_invalid_json(mocker):
|
||||||
mock_response = mocker.Mock(status_code=200)
|
mock_response = mocker.Mock(status_code=200)
|
||||||
mock_response.json.side_effect = requests.exceptions.RequestException("Error")
|
mock_response.json.side_effect = requests.exceptions.RequestException("Error")
|
||||||
mocker.patch("requests.get", return_value=mock_response)
|
mocker.patch("requests.get", return_value=mock_response)
|
||||||
|
|
||||||
condition = OffchainCondition(
|
condition = JsonApiCondition(
|
||||||
endpoint="https://api.example.com/data",
|
endpoint="https://api.example.com/data",
|
||||||
query="$.store.book[0].price",
|
query="$.store.book[0].price",
|
||||||
return_value_test=ReturnValueTest("==", "2"),
|
return_value_test=ReturnValueTest("==", "2"),
|
||||||
|
@ -118,7 +120,7 @@ def test_non_json_response(mocker):
|
||||||
|
|
||||||
mocker.patch("requests.get", return_value=mock_response)
|
mocker.patch("requests.get", return_value=mock_response)
|
||||||
|
|
||||||
condition = OffchainCondition(
|
condition = JsonApiCondition(
|
||||||
endpoint="https://api.example.com/data",
|
endpoint="https://api.example.com/data",
|
||||||
query="$.store.book[0].price",
|
query="$.store.book[0].price",
|
||||||
return_value_test=ReturnValueTest("==", "18"),
|
return_value_test=ReturnValueTest("==", "18"),
|
||||||
|
@ -130,9 +132,7 @@ def test_non_json_response(mocker):
|
||||||
assert "Failed to parse JSON response" in str(excinfo.value)
|
assert "Failed to parse JSON response" in str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
def test_basic_offchain_condition_evaluation_with_parameters(
|
def test_basic_json_api_condition_evaluation_with_parameters(mocker):
|
||||||
accounts, condition_providers, mocker
|
|
||||||
):
|
|
||||||
mocked_get = mocker.patch(
|
mocked_get = mocker.patch(
|
||||||
"requests.get",
|
"requests.get",
|
||||||
return_value=mocker.Mock(
|
return_value=mocker.Mock(
|
||||||
|
@ -140,7 +140,7 @@ def test_basic_offchain_condition_evaluation_with_parameters(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
condition = OffchainCondition(
|
condition = JsonApiCondition(
|
||||||
endpoint="https://api.coingecko.com/api/v3/simple/price",
|
endpoint="https://api.coingecko.com/api/v3/simple/price",
|
||||||
parameters={
|
parameters={
|
||||||
"ids": "ethereum",
|
"ids": "ethereum",
|
||||||
|
@ -154,9 +154,7 @@ def test_basic_offchain_condition_evaluation_with_parameters(
|
||||||
assert mocked_get.call_count == 1
|
assert mocked_get.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
def test_basic_offchain_condition_evaluation_with_headers(
|
def test_basic_json_api_condition_evaluation_with_headers(mocker):
|
||||||
accounts, condition_providers, mocker
|
|
||||||
):
|
|
||||||
mocked_get = mocker.patch(
|
mocked_get = mocker.patch(
|
||||||
"requests.get",
|
"requests.get",
|
||||||
return_value=mocker.Mock(
|
return_value=mocker.Mock(
|
||||||
|
@ -164,7 +162,7 @@ def test_basic_offchain_condition_evaluation_with_headers(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
condition = OffchainCondition(
|
condition = JsonApiCondition(
|
||||||
endpoint="https://api.coingecko.com/api/v3/simple/price",
|
endpoint="https://api.coingecko.com/api/v3/simple/price",
|
||||||
parameters={
|
parameters={
|
||||||
"ids": "ethereum",
|
"ids": "ethereum",
|
||||||
|
@ -180,9 +178,9 @@ def test_basic_offchain_condition_evaluation_with_headers(
|
||||||
assert mocked_get.call_args[1]["headers"]["Authorization"] == "Bearer 1234567890"
|
assert mocked_get.call_args[1]["headers"]["Authorization"] == "Bearer 1234567890"
|
||||||
|
|
||||||
|
|
||||||
def test_offchain_condition_from_lingo_expression():
|
def test_json_api_condition_from_lingo_expression():
|
||||||
lingo_dict = {
|
lingo_dict = {
|
||||||
"conditionType": "offchain",
|
"conditionType": "json-api",
|
||||||
"endpoint": "https://api.example.com/data",
|
"endpoint": "https://api.example.com/data",
|
||||||
"query": "$.store.book[0].price",
|
"query": "$.store.book[0].price",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
|
@ -199,8 +197,8 @@ def test_offchain_condition_from_lingo_expression():
|
||||||
}
|
}
|
||||||
|
|
||||||
cls = ConditionLingo.resolve_condition_class(lingo_dict, version=1.0)
|
cls = ConditionLingo.resolve_condition_class(lingo_dict, version=1.0)
|
||||||
assert cls == OffchainCondition
|
assert cls == JsonApiCondition
|
||||||
|
|
||||||
lingo_json = json.dumps(lingo_dict)
|
lingo_json = json.dumps(lingo_dict)
|
||||||
condition = OffchainCondition.from_json(lingo_json)
|
condition = JsonApiCondition.from_json(lingo_json)
|
||||||
assert isinstance(condition, OffchainCondition)
|
assert isinstance(condition, JsonApiCondition)
|
Loading…
Reference in New Issue