Spaces:
Running
Running
from __future__ import annotations | |
import re | |
import warnings | |
from typing import Any | |
class I18nData: | |
""" | |
A class that wraps a translation key with metadata. | |
This object will be serialized and sent to the frontend, where the actual | |
translation will happen using the frontend's i18n system. | |
""" | |
def __init__(self, key: str): | |
""" | |
Initialize a I18nData object. | |
Args: | |
key: The translation key to be translated in the frontend. | |
""" | |
self.key = key | |
self._type = "translation_metadata" | |
def to_dict(self) -> dict[str, Any]: | |
""" | |
Convert the I18nData object to a dictionary for serialization. | |
This allows the frontend to recognize it as a translatable object. | |
""" | |
return {"__type__": self._type, "key": self.key} | |
def __str__(self) -> str: | |
""" | |
String representation of the I18nData object. | |
Used when the object is converted to a string. | |
This returns a special format that can be recognized by the frontend | |
as needing translation. | |
""" | |
import json | |
return f"__i18n__{json.dumps(self.to_dict())}" | |
def __repr__(self) -> str: | |
""" | |
Representation of the I18nData object for debugging. | |
""" | |
return self.__str__() | |
def __add__(self, other): | |
""" | |
Handle string concatenation (self + other). | |
""" | |
return str(self) + str(other) | |
def __radd__(self, other): | |
""" | |
Handle string concatenation (other + self). | |
""" | |
return str(other) + str(self) | |
def __getattr__(self, name): | |
""" | |
Handle attribute access for I18nData. | |
This makes it possible to use I18nData objects in contexts | |
that expect strings with methods. | |
""" | |
if name.startswith("__") and name.endswith("__"): | |
raise AttributeError(f"{self.__class__.__name__} has no attribute {name}") | |
def method(*_args, **_kwargs): | |
return self | |
return method | |
def tojson(self) -> dict[str, Any]: | |
""" | |
Convert the I18nData object to a JSON-serializable dictionary. | |
This is used by the default Python JSON serializer. | |
""" | |
return self.to_dict() | |
class I18n: | |
""" | |
Handles internationalization (i18n) for Gradio applications. | |
Stores translation dictionaries and provides a method to retrieve translation keys. | |
The translation lookup happens on the frontend based on the browser's locale | |
and the provided translation dictionaries. | |
""" | |
# BCP 47 language tag regex pattern | |
_LOCALE_PATTERN = re.compile(r"^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$") | |
def __init__(self, **translations: dict[str, str]): | |
""" | |
Initializes the I18n class. | |
Args: | |
**translations: Each keyword argument should be a locale code (e.g., "en", "fr") with a | |
dictionary value, which maps translation keys to translated strings. | |
Example: gr.I18n(en={"greeting": "Hello"}, es={"greeting": "Hola"}) | |
These translations can be passed to the frontend for use there. | |
""" | |
self.translations = {} | |
for locale, translation_dict in translations.items(): | |
if not self._is_valid_locale(locale): | |
warnings.warn( | |
f"Invalid locale code: '{locale}'. Locale codes should follow BCP 47 format (e.g., 'en', 'en-US'). " | |
f"This locale will still be included, but may not work correctly.", | |
UserWarning, | |
) | |
self.translations[locale] = translation_dict | |
def _is_valid_locale(self, locale: str) -> bool: | |
return bool(self._LOCALE_PATTERN.match(locale)) | |
def __call__(self, key: str) -> I18nData: | |
""" | |
Returns a I18nData object containing the translation key. | |
This metadata object will be serialized and sent to the frontend, | |
where it will be translated by the frontend's i18n system. | |
Args: | |
key: The key to identify the translation string (e.g., "submit_button"). | |
Returns: | |
A I18nData object containing the translation key. | |
""" | |
return I18nData(key) | |
def translations_dict(self) -> dict[str, dict[str, str]]: | |
""" | |
Returns the dictionary of translations provided during initialization. | |
These can be passed to the frontend for use in its translation system. | |
""" | |
return self.translations | |