Миграция с консоли
Замена get_lang_code_by_provider_and_language и get_language_by_code на HTTP-вызов.
Консоль (animated-spoon) резолвит коды языков в cabinet/helpers.py. Этот сервис заменяет те хелперы. Поведение совместимо по построению — миграция механическая.
Соответствие
| Хелпер консоли | Этот сервис |
|---|---|
get_lang_code_by_provider_and_language(service_name, language) |
GET /v1/resolve?provider=…&language=… → code |
get_language_by_code(code) |
GET /v1/normalize?language=… → language |
get_exact_language(code) |
GET /v1/languages/{code} (404 если неизвестно; без фолбэка на базовый) |
get_lang_code(language) |
GET /v1/languages/{code} → code |
Language.full_abbreviation() |
GET /v1/languages/{code} → code |
Аргументы менять не нужно
provider принимает service_name консоли дословно. Каждая из 106 строк translation_provider и все 14 строк translation_automlprovider зарегистрированы как алиасы провайдеров:
# было
code = get_lang_code_by_provider_and_language("OpenAiGPT4o_2024_11_20_Provider", language)
# стало — та же строка, тот же ответ
code = client.get(
"/v1/resolve",
params={
"provider": "OpenAiGPT4o_2024_11_20_Provider",
"language": language.full_abbreviation(),
},
).json()["code"]
language принимает всё, что приняла бы консоль: двухбуквенную аббревиатуру, любой региональный код, любой регистр.
Что изменилось осознанно
Неоднозначные пары теперь имеют один ответ. 330 пар (провайдер, язык) имели несколько кодов, и .first() в Django брал ту строку, которую отдал Postgres. Какой код использовала ваша задача — на практике было произвольно. Теперь это зафиксировано и задокументировано, и каждое написание-проигравший остаётся входящим алиасом, так что ничто, что резолвилось раньше, не перестаёт. Полный перечень решений — в data/seed/REPORT.md.
Сломанные коды исправлены. Код себуанского в консоли начинается с кириллической с, так что get_language_by_code("ceb") никогда в него не попадал. Здесь — попадает.
Обрезание code[:2] стало настоящим поиском. Консоль заканчивается на lang_region_list.code[:2] — первые два символа произвольного регионального кода. Для ceb-latn-ph это даёт ce, то есть чеченский. Этот сервис вместо этого идёт к настоящей строке базового языка, так что ceb остаётся ceb.
Провайдеры уровня модели свернулись. OpenAI GPT 4o-2024-11-20 и OpenAI GPT 5-mini — это оба openai_api. Их таблицы языков в консоли были почти идентичны; где они различались, побеждал выбор более новой модели. См. Providers and Vendors.
Что не изменилось
Всё остальное. Каждый базовый язык по-прежнему резолвится в собственный код без маппинга, и каждый региональный без маппинга по-прежнему фолбэчится в базовый — те же два правила, что и в консоли, в том же порядке. См. Resolution Ladder.
Резолвите оба языка одним вызовом
Задаче нужны source и target. Не делайте два запроса:
pairs = [
{"provider": provider, "language": source_code},
{"provider": provider, "language": target_code},
]
items = client.post("/v1/resolve/batch", json={"pairs": pairs}).json()["items"]
source_lang, target_lang = (item["result"]["code"] for item in items)
Рекомендуемый раскат
- Тень. Вызывайте этот сервис параллельно с существующим хелпером и логируйте расхождения. Ожидаемые — только на 330 неоднозначных парах и на себуанском.
- Переключите чтения. Замените хелпер. Оставьте
service_nameкак аргумент провайдера — больше ничего менять не нужно. - Перейдите на канонические коды. Храните
languageиз ответа вместо сырого входящего написания. Именно этот шаг делает записи сравнимыми; делайте его когда удобно, а не как предусловие. - Выведите таблицы консоли из эксплуатации, когда из них никто не читает.
Обработка сбоев
Сервис — зависимость на пути перевода. Две вещи делают это безопасным:
- Кеш. Каталог меняется несколько раз в месяц. Кешировать
(provider, language) → codeна минуты безопасно, и это убирает сервис с вашего горячего пути вовсе. - Фолбэк на входящее значение. Если вызов упал и кешированного ответа нет, отправить канонический код, который у вас уже есть, — это то же, что дала бы политика
passthrough. Залогируйте это; не валите задачу.
Далее
- Resolution Ladder — что означают ответы
- Endpoints Index — всё доступное