Translation
Сервис переводов
Для понимания это управление умной экселькой, в которой первая колонка это ключ перевода, а вторая и последующие колонки - перевод на разных языках (каждая колонка - это новый язык)
Make New Enc Keys
ulapiutls enc_keys --algorithm RS256 --follower-services translation-web --service-name translation-auth --jwt-permissions-module src.conf.permissions --jwt-environment local --jwt-user-id 6ff8eaba-b5b4-49b2-9a83-f48fcdf6d361
Services
- translation__balancer = nginx
- translation__public_api = flask+sqlalchemy
- translation__internal_api = flask+sqlalchemy
- translation__auth_api = COMMON SERVICE
- translation__management_view = flask+jingja2
- translation__db = pg14
- translation__db_ui = pgweb
Структура хранимых данных
lang:
id: uuid, pk
user_created: uuid, fk(api_user)
user_modified: uuid, fk(api_user)
date_created: date-time, utc
date_modified: date-time, utc
is_alive: bool
name: str(255), uniq # human readable text in ANY LANGUAGE
abbr: str(10), uniq, ASCII symbols only, RESTRICT WHITE SPACES # exaples - en, ru, en_EN, en_US, ...
key:
id: uuid, pk
user_created: uuid, fk(api_user)
user_modified: uuid, fk(api_user)
date_created: date-time, utc
date_modified: date-time, utc
is_alive: bool
name: str(255), uniq, ASCII symbols only, RESTRICT WHITE SPACES !!!! # examples - "account.something.0.else", "user_profile.full_name", "name"
translation: # не может стать удаленным или помечен быть как удален
id: uuid, pk
user_created: uuid, fk(api_user)
user_modified: uuid, fk(api_user)
date_created: date-time, utc
date_modified: date-time, utc
lang_id: fk(lang)
key_id: fk(key)
content: text # ЛЮБАЯ СТРОКА. БЕЗ ВАЛИДАЦИИ. ПУСТАЯ СТРОКА ВАЛИДНА
translation_cache: # material-view, trigger(translation, key, lang). ТОЛЬКО активные записи
translation_id: uuid, fk(translation)
lang_abbr: str(10)
key_name: str(255)
translation_content: text
# constaint: uniq_together(lang_id, key_id, content)
PUBLIC API service
GET /lang/en_EN/translation-cache
где en_EN - это существующая абривиатура языка
нет авторизации. ЛЮБОЙ может получить ответ
Кэш запроса на уровне nginx = 1 час
Строится ответ по таблице translation-cache
ключи сортируются согласно alpha-numeric
{
"key.name": "translation_content",
"field.0.some": "translation_content 2",
/*другие ключи этого языка и переводы к ним*/
}
если такого языка не найдено в translation_cache то возвращается пустой обьект со статусом 404
GET /lang/en_EN/translation-cache-compiled
тоже самое что и GET /lang/en_EN/translation-cache НО ключи разворачиваются согласно точкам в структуры обьектов
если точка вначале или в конце - игнорируются
Напрмер key.name - это вложенные обьекты. в первом есть атрибут key и его значение равен обьекту у которого есть ключ name. пустая строка = валидное проперти обьекта
{
"key": {
"name": "translation_content",
},
"field": {
"0": {
"some": "translation_content 2"
}
},
/*другие ключи этого языка и переводы к ним*/
}
Решением построения дерева предлагается как утилитарная функция
def set_obj_attr_by_path(mut_obj: Dict[str, Any], path_key: str, value: Any) -> NDict[str, Any]:
obj = mut_obj
segments = path_key.strip(".").split(".")
for i, segment in enumerate(segments):
if i == (len(segments) - 1):
obj[segment] = value
else:
if segment not in obj:
obj[segment] = dict()
obj = obj[segment]
return mut_obj
INTERNAL API service
Languages API
GET /langs
Получение списка всех (даже неактивных) языков
(при создании нового, создаются записи для всех переводов translation по всем существующим ключам с пустым контентом)
/* Response example */
[
{
"id": "...",
"user_created": "...",
"user_modified": "...",
"date_created": "...",
"date_modified": "...",
"is_alive": "...",
"name": "English",
"abbr": "en_EN",
},
...
]
GET /langs/:id
Получение списка конкретного языка
/* Response example */
{
"id": "...",
"user_created": "...",
"user_modified": "...",
"date_created": "...",
"date_modified": "...",
"is_alive": "...",
"name": "English",
"abbr": "en_EN",
}
POST /langs/
Созданиен языка
/* Request example */
{
"name": "Russian",
"abbr": "ru_RU",
}
PUT /langs/:id
Изменение конкретного языка
/* Request example */
{
"id": "...",
"user_created": "...",
"user_modified": "...",
"date_created": "...",
"date_modified": "...",
"is_alive": "...",
"name": "Russian",
"abbr": "ru_RU",
}
DELETE /langs/:id
Удаление конкретного языка
Keys API
GET /keys
Получение списка всех (даже неактивных) ключей
/* Response example */
[
{
"id": "...",
"user_created": "...",
"user_modified": "...",
"date_created": "...",
"date_modified": "...",
"is_alive": "...",
"name": "field.3.some",
},
...
]
GET /keys/:id
Получение списка конкретного ключа
/* Response example */
{
"id": "...",
"user_created": "...",
"user_modified": "...",
"date_created": "...",
"date_modified": "...",
"is_alive": "...",
"name": "field.3.some",
}
POST /keys/
Созданиен ключа
/* Request example */
{
"name": "field.3.some",
}
PUT /keys/:id
Изменение конкретного ключа
/* Request example */
{
"id": "...",
"user_created": "...",
"user_modified": "...",
"date_created": "...",
"date_modified": "...",
"is_alive": "...",
"name": "field.3.some",
}
DELETE /keys/:id
Удаление конкретного языка
Translation API
GET /translations
Получение списка всех переводов
/* Response example */
[
{
"translation_id": "fk(translation).id",
"lang_abbr": "en_EN",
"key_name": "field.3.some",
"translation_content": "",
},
...
]
GET /translations/:id
Получение списка конкретного переводов
/* Response example */
{
"translation_id": "fk(translation).id",
"lang_abbr": "en_EN",
"key_name": "fields.3.some",
"translation_content": "some text",
}
POST /translations
Созданиен ключа
/* Request example */
{
"translation_id": "fk(translation).id",
"content": "some text",
}
PUT /translations
Изменение конкретного ключа
/* Request example */
[
{
"translation_id": "fk(translation).id",
"content": "some text",
}
]
View service
Работает через логин в котором вставляется токен авторизации в поле при старте приложения
Токен генерируется в Auth Api
pages:
- Login
- Lang
- Keys
- Translation
- Import *
- Export *
Login Page
Одно поле - токен, который потом записывается в куку, если токен валиден
Lang Page
это таблица со всеми языками (даже с неактивными)
можно редактировать языки, добавлять, удалять - через модалку
модалка - поля, кнопка сохранить, кнопка отменить
Keys Page
это таблица со всеми ключами (даже с неактивными)
можно редактировать ключи, добавлять, удалять - через модалку
модалка - поля, кнопка сохранить, кнопка отменить
Translation Page
таблица строится по translation_cache и key
Выводятся Абсолютно все активные записи
колонки:
- ПЕРВАЯ КОЛОНКА = key_name всех активных ключей
- остальные колонки это все доступные АКТИВНЫЕ языки и переводы к ним
Ячейки в которых нет текста должны подстветиться оранжевым (или другим ярким) цветом
строки отсортированы по имени ключа
Нажимая на строку (или только на ключ строки) открывается модалка с изменениями сразу всех возможных переводов для данного ключа. ключ менять нельзя. после применения страница перезагружается
модалка - поля, кнопка сохранить, кнопка отменить
Export Page *
Кнопка с генерацией файла на скачку
Формат файла - JSON
Экспортируются ТОЛЬКО активные записи !
{
"langs": [{/*... все поля языков*/}, /*...*/],
"key": [{/*... все поля ключей*/}, /*...*/],
"translation": [{/*... все поля переводов*/, /*...*/}],
}
Import Page *
На странице есть кнопка с загрузкой файла
Формат файла точно соответсвует формату файла экспорта.
Любое несоотвествие, лишние поля итп - ошибка !
Если такой айди существует - контент заменяется
Применяется одной транзакцией
Metadata
Release files for ul-translation-sdk 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ul_translation_sdk-3.0.0.tar.gz | 14.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ul_translation_sdk-3.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.7 kB
Release files / ul_translation_sdk-3.0.0.tar.gz
| Download URL | ul_translation_sdk-3.0.0.tar.gz |
|---|---|
| Size | 14.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ee24fa2e505ddf1099a17f636e757f99c66d21164faad0b39f76d19accab3bcd
|
|
BLAKE2b-256 checksum How to use checksums |
9593522a28c25851fa990dd5992ee1a24d7a418d8901a28d9441f96c9f219f2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / ul_translation_sdk-3.0.0-py3-none-any.whl
| Download URL | ul_translation_sdk-3.0.0-py3-none-any.whl |
|---|---|
| Size | 14.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d4155b59bb561f1df29bc5132b9c7dbae08b35058a1de9e5cbbe770ac92c2305
|
|
BLAKE2b-256 checksum How to use checksums |
f0eb23d9b3009bfb1eb60a669aa6ae537a5732b368e7f42c48a5ad0ee0aa80b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|