Skip to content

Commit b7e483d

Browse files
dracozombie19leandrodamascenasthulb
authored
feat(validation): returns output from validate function (#4839)
* Return the output of fastjsonschema.validate() * Adding documentation --------- Co-authored-by: Leandro Damascena <[email protected]> Co-authored-by: Simon Thulbourn <[email protected]>
1 parent 67eaf01 commit b7e483d

File tree

5 files changed

+75
-14
lines changed

5 files changed

+75
-14
lines changed

aws_lambda_powertools/utilities/validation/base.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def validate_data_against_schema(
1414
formats: Optional[Dict] = None,
1515
handlers: Optional[Dict] = None,
1616
provider_options: Optional[Dict] = None,
17-
):
17+
) -> Union[Dict, str]:
1818
"""Validate dict data against given JSON Schema
1919
2020
Parameters
@@ -31,6 +31,12 @@ def validate_data_against_schema(
3131
Arguments that will be passed directly to the underlying validation call, in this case fastjsonchema.validate.
3232
For all supported arguments see: https://horejsek.github.io/python-fastjsonschema/#fastjsonschema.validate
3333
34+
Returns
35+
-------
36+
Dict
37+
The validated event. If the schema specifies a `default` value for fields that are omitted,
38+
those default values will be included in the response.
39+
3440
Raises
3541
------
3642
SchemaValidationError
@@ -42,7 +48,13 @@ def validate_data_against_schema(
4248
formats = formats or {}
4349
handlers = handlers or {}
4450
provider_options = provider_options or {}
45-
fastjsonschema.validate(definition=schema, data=data, formats=formats, handlers=handlers, **provider_options)
51+
return fastjsonschema.validate(
52+
definition=schema,
53+
data=data,
54+
formats=formats,
55+
handlers=handlers,
56+
**provider_options,
57+
)
4658
except (TypeError, AttributeError, fastjsonschema.JsonSchemaDefinitionException) as e:
4759
raise InvalidSchemaFormatError(f"Schema received: {schema}, Formats: {formats}. Error: {e}")
4860
except fastjsonschema.JsonSchemaValueException as e:

aws_lambda_powertools/utilities/validation/validator.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def validate(
172172
provider_options: Optional[Dict] = None,
173173
envelope: Optional[str] = None,
174174
jmespath_options: Optional[Dict] = None,
175-
):
175+
) -> Any:
176176
"""Standalone function to validate event data using a JSON Schema
177177
178178
Typically used when you need more control over the validation process.
@@ -245,6 +245,12 @@ def handler(event, context):
245245
validate(event=event, schema=json_schema_dict, envelope="awslogs.powertools_base64_gzip(data) | powertools_json(@).logEvents[*]")
246246
return event
247247
248+
Returns
249+
-------
250+
Dict
251+
The validated event. If the schema specifies a `default` value for fields that are omitted,
252+
those default values will be included in the response.
253+
248254
Raises
249255
------
250256
SchemaValidationError
@@ -261,7 +267,7 @@ def handler(event, context):
261267
jmespath_options=jmespath_options,
262268
)
263269

264-
validate_data_against_schema(
270+
return validate_data_against_schema(
265271
data=event,
266272
schema=schema,
267273
formats=formats,

docs/utilities/validation.md

+4
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ It will fail fast with `SchemaValidationError` exception if event or response do
6767

6868
**Validate** standalone function is typically used within the Lambda handler, or any other methods that perform data validation.
6969

70+
???+ info
71+
This function returns the validated event as a JSON object. If the schema specifies `default` values for omitted fields,
72+
those default values will be included in the response.
73+
7074
You can also gracefully handle schema validation errors by catching `SchemaValidationError` exception.
7175

7276
=== "getting_started_validator_standalone_function.py"

tests/functional/validator/_fastjsonschema/test_validator.py

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ def test_validate_raw_event(schema, raw_event):
1616
validate(event=raw_event, schema=schema)
1717

1818

19+
def test_validate_raw_event_default(schema_default, raw_event_default):
20+
resp = validate(event=raw_event_default, schema=schema_default)
21+
assert resp["username"] == "blah blah"
22+
assert resp["message"] == "The default message"
23+
24+
1925
def test_validate_wrapped_event_raw_envelope(schema, wrapped_event):
2026
validate(event=wrapped_event, schema=schema, envelope="data.payload")
2127

tests/functional/validator/conftest.py

+43-10
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
@pytest.fixture
77
def schema():
88
return {
9-
"$schema": "http://json-schema.org/draft-07/schema",
10-
"$id": "http://example.com/example.json",
9+
"$schema": "https://json-schema.org/draft-07/schema",
10+
"$id": "https://example.com/example.json",
1111
"type": "object",
1212
"title": "Sample schema",
1313
"description": "The root schema comprises the entire JSON document.",
@@ -30,11 +30,39 @@ def schema():
3030
}
3131

3232

33+
@pytest.fixture
34+
def schema_default():
35+
return {
36+
"$schema": "https://json-schema.org/draft-07/schema",
37+
"$id": "https://example.com/example.json",
38+
"type": "object",
39+
"title": "Sample schema",
40+
"description": "The root schema comprises the entire JSON document.",
41+
"examples": [{"message": "hello world", "username": "lessa"}, {"username": "lessa"}],
42+
"required": ["username"],
43+
"properties": {
44+
"message": {
45+
"$id": "#/properties/message",
46+
"type": "string",
47+
"title": "The message",
48+
"examples": ["hello world"],
49+
"default": "The default message",
50+
},
51+
"username": {
52+
"$id": "#/properties/username",
53+
"type": "string",
54+
"title": "The username",
55+
"examples": ["lessa"],
56+
},
57+
},
58+
}
59+
60+
3361
@pytest.fixture
3462
def schema_array():
3563
return {
36-
"$schema": "http://json-schema.org/draft-07/schema",
37-
"$id": "http://example.com/example.json",
64+
"$schema": "https://json-schema.org/draft-07/schema",
65+
"$id": "https://example.com/example.json",
3866
"type": "array",
3967
"title": "Sample schema",
4068
"description": "Sample JSON Schema for dummy data in an array",
@@ -71,8 +99,8 @@ def schema_array():
7199
@pytest.fixture
72100
def schema_response():
73101
return {
74-
"$schema": "http://json-schema.org/draft-07/schema",
75-
"$id": "http://example.com/example.json",
102+
"$schema": "https://json-schema.org/draft-07/schema",
103+
"$id": "https://example.com/example.json",
76104
"type": "object",
77105
"title": "Sample outgoing schema",
78106
"description": "The root schema comprises the entire JSON document.",
@@ -89,7 +117,7 @@ def schema_response():
89117
def schema_refs():
90118
return {
91119
"ParentSchema": {
92-
"$schema": "http://json-schema.org/draft-07/schema",
120+
"$schema": "https://json-schema.org/draft-07/schema",
93121
"$id": "testschema://ParentSchema",
94122
"type": "object",
95123
"title": "Sample schema",
@@ -104,7 +132,7 @@ def schema_refs():
104132
},
105133
},
106134
"ChildSchema": {
107-
"$schema": "http://json-schema.org/draft-07/schema",
135+
"$schema": "https://json-schema.org/draft-07/schema",
108136
"$id": "testschema://ChildSchema",
109137
"type": "object",
110138
"title": "Sample schema",
@@ -137,6 +165,11 @@ def raw_event():
137165
return {"message": "hello hello", "username": "blah blah"}
138166

139167

168+
@pytest.fixture
169+
def raw_event_default():
170+
return {"username": "blah blah"}
171+
172+
140173
@pytest.fixture
141174
def wrapped_event():
142175
return {"data": {"payload": {"message": "hello hello", "username": "blah blah"}}}
@@ -407,7 +440,7 @@ def cloudwatch_logs_event():
407440
@pytest.fixture
408441
def cloudwatch_logs_schema():
409442
return {
410-
"$schema": "http://json-schema.org/draft-07/schema",
443+
"$schema": "https://json-schema.org/draft-07/schema",
411444
"$id": "http://example.com/example.json",
412445
"type": "array",
413446
"title": "Sample schema",
@@ -622,7 +655,7 @@ def eventbridge_schema_registry_cloudtrail_v2_s3():
622655
@pytest.fixture
623656
def schema_datetime_format():
624657
return {
625-
"$schema": "http://json-schema.org/draft-07/schema",
658+
"$schema": "https://json-schema.org/draft-07/schema",
626659
"$id": "http://example.com/example.json",
627660
"type": "object",
628661
"title": "Sample schema with string date-time format",

0 commit comments

Comments
 (0)