Skip to content

Commit a8def40

Browse files
committed
Add validation to schema interface
1 parent c7f4f33 commit a8def40

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

src/aws_schema_registry/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from .client import SchemaRegistryClient
22
from .exception import SchemaRegistryException
3-
from .schema import CompatibilityMode, DataFormat, Schema, SchemaVersion
3+
from .schema import (
4+
CompatibilityMode, DataFormat, Schema, SchemaVersion, ValidationError
5+
)
46
from .serde import (
57
DataAndSchema, SchemaRegistryDeserializer, SchemaRegistrySerializer
68
)
@@ -16,5 +18,6 @@
1618
'SchemaRegistryDeserializer',
1719
'SchemaRegistryException',
1820
'SchemaRegistrySerializer',
19-
'SchemaVersion'
21+
'SchemaVersion',
22+
'ValidationError'
2023
]

src/aws_schema_registry/avro.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import fastavro
77

8-
from aws_schema_registry.schema import DataFormat, Schema
8+
from aws_schema_registry.schema import DataFormat, Schema, ValidationError
99

1010

1111
class AvroSchema(Schema):
@@ -63,3 +63,12 @@ def write(self, data) -> bytes:
6363
value = b.getvalue()
6464
b.close()
6565
return value
66+
67+
def validate(self, data):
68+
try:
69+
fastavro.validate(data, self._parsed)
70+
except Exception as e:
71+
# the message will contain space characters, json.loads + str is a
72+
# (relatively inefficient) way to remove them
73+
detail: list[str] = json.loads(str(e))
74+
raise ValidationError(str(detail)) from e

src/aws_schema_registry/schema.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ def read(self, bytes_: bytes) -> Any:
5555
def write(self, data) -> bytes:
5656
"""Write a record into bytes."""
5757

58+
def validate(self, data) -> None:
59+
"""Raise a ValidationException if the data is invalid."""
60+
61+
62+
class ValidationError(Exception):
63+
"""Raised when a schema's `validate` is called on invalid data.
64+
65+
The error need not contain *every* validation error, just the first that
66+
classifies the data as invalid.
67+
"""
68+
pass
69+
5870

5971
@dataclass
6072
class SchemaVersion:

tests/test_avro.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import pytest
2+
3+
from aws_schema_registry import ValidationError
14
from aws_schema_registry.avro import AvroSchema
25

36

@@ -27,3 +30,24 @@ def test_readwrite():
2730
'age': 900
2831
}
2932
assert s.read(s.write(d)) == d
33+
34+
35+
def test_validation():
36+
s = AvroSchema('''
37+
{
38+
"type": "record",
39+
"name": "JediMaster",
40+
"fields": [
41+
{"name": "name", "type": "string" },
42+
{"name": "age", "type": "int" }
43+
]
44+
}''')
45+
with pytest.raises(ValidationError) as e:
46+
s.validate({'name': 'Obi-Wan'})
47+
assert 'name' not in str(e)
48+
assert 'age' in str(e)
49+
with pytest.raises(ValidationError) as e:
50+
s.validate({'name': 1, 'age': 2})
51+
assert 'name' in str(e)
52+
assert 'age' not in str(e)
53+
s.validate({'name': 'Jar Jar', 'age': 42, 'sith': True})

0 commit comments

Comments
 (0)