I have question about l10n and i18n. Are possible to localize error messages using Python gettext for example?
I guess you mean "L10n" for "Localisation"?
Pydantic doesn't come with build in support for internationalisation or translation, but it does provide a hook to make it easier.
You should use the type field on errors to to look up a more appropriate message, then use the ctx field to populate the message with any necessary values.
Here's a very simple example:
from pydantic import BaseModel, ValidationError, FilePath
from devtools import debug
def _(msg_id):
"""
Very simple translation engine to demonstate,
use gettext in real life with mo, po files etc.
"""
translations = {
'Value is not a valid float': "La valeur n'est pas un float valide",
'Not a valid path: "{path}"': 'Chemin non valide: "{path}"',
}
try:
return translations[msg_id]
except TypeError as e:
raise RuntimeError(f'no translations for "{msg_id}"') from e
messages = {
'type_error.float': _('Value is not a valid float'),
'value_error.path.not_exists': _('Not a valid path: "{path}"'),
# ... other translations
}
class Model(BaseModel):
a: float
p: FilePath
try:
Model(a='foo', p='/does/not/exist')
except ValidationError as e:
# raw errors:
debug(e.errors())
# errors again but translated:
translated_errors = {}
for error in e.errors():
msg = messages[error['type']]
ctx = error.get('ctx')
if ctx:
msg = msg.format(**ctx)
translated_errors[error['loc'][0]] = msg
debug(translated_errors)
Where debug is installed from the devtools package.
If you're only using the package in one other language eg. Russian you could dispense with gettext etc. all together and just use Russian values in messages above.
You can find all the types in errors.py
@samuelcolvin - great to see this, was just wondering about it, I wonder if it's worth re-opening this as a documentation issue, or did I miss more docs somewhere? :-)
Absolutely, pr welcome.
Just to mention that the 'type' naming logic is here, or in pydantic.error_wrappers:_get_exc_type.
Most helpful comment
I guess you mean "L10n" for "Localisation"?
Pydantic doesn't come with build in support for internationalisation or translation, but it does provide a hook to make it easier.
You should use the
typefield on errors to to look up a more appropriate message, then use thectxfield to populate the message with any necessary values.Here's a very simple example:
Where debug is installed from the devtools package.
If you're only using the package in one other language eg. Russian you could dispense with gettext etc. all together and just use Russian values in
messagesabove.You can find all the
types in errors.py