Нормалізація вхідних кодів
Як перетворити купу неузгоджених кодів від інтеграції на канонічні.
Мета: інтеграція шле вам pt_BR, POR-BR, zh_hans, iw, xx-YY. Вам потрібні канонічні коди й список того, що не вдалось розпізнати — без провайдера в картині.
/v1/normalize відповідає саме на це, і невідомий код тут не помилка:
curl "https://languages.service.custom.mt/v1/normalize?language=ZH_HANS"
{ "query": "ZH_HANS", "known": true, "matched_alias": "zh-hans",
"language": { "code": "zh-CN", "name": "Chinese (Simplified)",
"kind": "regional", "base_language_code": "zh", … } }
curl "https://languages.service.custom.mt/v1/normalize?language=xx-YY"
{ "query": "xx-YY", "language": null, "matched_alias": null, "known": false }
Обидва рази 200. Це навмисно: класифікувати список за один прохід краще, ніж ловити 404 у циклі.
Чистка всього списку
def classify(codes: list[str]) -> tuple[dict[str, str], list[str]]:
"""Повертає {вхід: канонічний} і список кодів, які не вдалось розпізнати."""
canonical, unknown = {}, []
for code in codes:
body = httpx.get(f"{BASE}/v1/normalize", params={"language": code}).json()
if body["known"]:
canonical[code] = body["language"]["code"]
else:
unknown.append(code)
return canonical, unknown
Список unknown — це той результат, з яким можна щось робити: кожен запис — або одрук на їхньому боці, або відсутній аліас на нашому. Реальні додайте з адмінки — див. Додати мову.
Зберігання канонічного коду
Зберігайте language.code, а не сирий ввід. Саме це робить два записи порівнюваними: проєкт, збережений як pt_BR, і проєкт як por-br — це та сама мова, але без нормалізації ви цього не дізнаєтесь.
Тримайте й сире значення, якщо треба відповідати ним інтеграції.
Пошук дублікатів, які у вас уже є
canonical, _ = classify(existing_codes)
from collections import Counter
for code, count in Counter(canonical.values()).items():
if count > 1:
print(f"{code}: {[k for k, v in canonical.items() if v == code]}")
# zh-CN: ['zh_hans', 'zh-CN', 'CHS']
Три рядки у вашій базі, одна мова.
Далі
- Aliases and Normalisation — правила, що за цим стоять