Source code for zero_ex.json_schemas
"""0x JSON schemas and associated utilities.
Setup
-----
Install the package with pip::
pip install 0x-json-schemas
"""
from os import path
import json
from typing import Mapping
from pkg_resources import resource_string
import jsonschema
from stringcase import snakecase
class _LocalRefResolver(jsonschema.RefResolver):
"""Resolve package-local JSON schema id's."""
def __init__(self):
"""Initialize a new instance."""
jsonschema.RefResolver.__init__(self, "", "")
@staticmethod
def resolve_from_url(url: str) -> str:
"""Resolve the given URL.
:param url: a string representing the URL of the JSON schema to fetch.
:returns: a string representing the deserialized JSON schema
:raises jsonschema.ValidationError: when the resource associated with
`url` does not exist.
"""
ref = url.replace("file://", "")
return json.loads(
resource_string(
"zero_ex.json_schemas",
f"schemas/{snakecase(ref.lstrip('/'))}.json",
)
)
# Instantiate the `_LocalRefResolver()` only once so that `assert_valid()` can
# perform multiple schema validations without reading from disk the schema
# every time.
_LOCAL_RESOLVER = _LocalRefResolver()
[docs]def assert_valid(data: Mapping, schema_id: str) -> None:
"""Validate the given `data` against the specified `schema`.
:param data: Python dictionary to be validated as a JSON object.
:param schema_id: id property of the JSON schema to validate against. Must
be one of those listed in `the 0x JSON schema files
<https://github.com/0xProject/0x-monorepo/tree/development/packages/json-schemas/schemas>`_.
Raises an exception if validation fails.
>>> from zero_ex.json_schemas import assert_valid
>>> from zero_ex.contract_addresses import chain_to_addresses, ChainId
>>> from eth_utils import remove_0x_prefix
>>> import random
>>> from datetime import datetime, timedelta
>>> assert_valid(
... {'makerAddress': '0x5409ed021d9299bf6814279a6a1411a7e866a631',
... 'takerAddress': '0x0000000000000000000000000000000000000000',
... 'senderAddress': '0x0000000000000000000000000000000000000000',
... 'exchangeAddress': '0x4f833a24e1f95d70f028921e27040ca56e09ab0b',
... 'feeRecipientAddress': (
... '0x0000000000000000000000000000000000000000'
... ),
... 'makerAssetData': (
... chain_to_addresses(ChainId.MAINNET).zrx_token
... ),
... 'takerAssetData': (
... chain_to_addresses(ChainId.MAINNET).ether_token
... ),
... 'salt': random.randint(1, 100000000000000000),
... 'makerFee': 0,
... 'makerFeeAssetData': '0x' + '00'*20,
... 'takerFee': 0,
... 'takerFeeAssetData': '0x' + '00'*20,
... 'makerAssetAmount': 1000000000000000000,
... 'takerAssetAmount': 500000000000000000000,
... 'expirationTimeSeconds': round(
... (datetime.utcnow() + timedelta(days=1)).timestamp()
... ),
... 'chainId': 50
... },
... "/orderSchema"
... )
"""
_, schema = _LOCAL_RESOLVER.resolve(schema_id)
jsonschema.validate(data, schema, resolver=_LOCAL_RESOLVER)
[docs]def assert_valid_json(data: str, schema_id: str) -> None:
"""Validate the given `data` against the specified `schema`.
:param data: JSON string to be validated.
:param schema_id: id property of the JSON schema to validate against. Must
be one of those listed in `the 0x JSON schema files
<https://github.com/0xProject/0x-monorepo/tree/development/packages/json-schemas/schemas>`_.
Raises an exception if validation fails.
>>> assert_valid_json(
... '''{
... "v": 27,
... "r": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
... "s": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
... }''',
... '/ecSignatureSchema',
... )
""" # noqa: E501 (line too long)
assert_valid(json.loads(data), schema_id)