Messages¶
Zangar provides a fully customizable message management system. You can write your own custom messages or modify Zangar’s default messages.
Custom Messages¶
Functions like zangar.ensure, zangar.transform, zangar.int, zangar.to.int, etc., all accept a message keyword argument to customize messages.
For example:
>>> z.ensure(lambda x: len(x) > 5, message="Too short").parse("hello")
Traceback (most recent call last):
zangar.exceptions.ValidationError: [{'msgs': ['Too short']}]
You can also pass a function, which will receive the parsed value as its argument, allowing you to construct clearer messages.
>>> z.int(message=lambda x: f"I need an integer instead of {x!r}").parse("hello")
Traceback (most recent call last):
zangar.exceptions.ValidationError: [{'msgs': ["I need an integer instead of 'hello'"]}]
Required Field Messages¶
Required fields can also have custom messages as shown below.
>>> z.struct({
... 'username': z.field(z.str()).required(message='Username is required.'),
... }).parse({})
Traceback (most recent call last):
zangar.exceptions.ValidationError: [{'msgs': ['Username is required.'], 'loc': ['username']}]
Warning
If the message for a required field is a function, since there is no corresponding parsed value, the function will receive None as its argument.
Not Just Strings¶
Messages can be any type you want (except None), not just strings.
>>> z.struct({
... 'username': z.field(z.str()).required(message={'code': 1001, 'description': 'This field is required.'}),
... }).parse({})
Traceback (most recent call last):
zangar.exceptions.ValidationError: [{'msgs': [{'code': 1001, 'description': 'This field is required.'}], 'loc': ['username']}]
Modifying Default Messages¶
Zangar’s built-in validation methods all have default messages, but they may not be what you want. Zangar provides a way to modify default messages via a context object, so you can change the default messages where needed.
class MyMessageContext(z.MessageContext):
def process_message(self, message):
if isinstance(message, z.DefaultMessage):
if message.key == 'field_required':
return 'Required field'
return super().process_message(message)
>>> with MyMessageContext():
... z.struct({
... 'username': z.field(z.str()).required(),
... }).parse({})
Traceback (most recent call last):
zangar.exceptions.ValidationError: [{'msgs': ['Required field'], 'loc': ['username']}]
Zangar’s default messages are wrapped in a zangar.DefaultMessage object. It contains additional information that can be used to customize messages.
Below is a list of the built-in default messages:
Key |
Message |
|---|---|
datetime_is_aware |
“The datetime should be aware” |
datetime_is_naive |
“The datetime should be naive” |
field_required |
“This field is required” |
number_gt |
“The value should be greater than {ctx[gt]}” |
number_gte |
“The value should be greater than or equal to {ctx[gte]}” |
number_lt |
“The value should be less than {ctx[lt]}” |
number_lte |
“The value should be less than or equal to {ctx[lte]}” |
str_max |
“The maximum length of the string is {ctx[max]}” |
str_min |
“The minimum length of the string is {ctx[min]}” |
transform_failed |
“{ctx[exc]}” |
type_check |
“Expected {ctx[expected_type].__name__}, received {value.__class__.__name__}” |
type_convertion |
“Cannot convert the value {value!r} to {ctx[expected_type].__name__}” |
unknown_field |
“Unknown field” |