Migrating from the Console
Replacing get_lang_code_by_provider_and_language and get_language_by_code with an HTTP call.
The console (animated-spoon) resolves language codes in cabinet/helpers.py. This service replaces those helpers. The behaviour is compatible by construction — the migration is mechanical.
The mapping
| Console helper | This service |
|---|---|
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 if unknown; no base fallback) |
get_lang_code(language) |
GET /v1/languages/{code} → code |
Language.full_abbreviation() |
GET /v1/languages/{code} → code |
You do not have to change the arguments
provider accepts the console's service_name verbatim. Every one of the 106 translation_provider rows and all 14 translation_automlprovider rows is registered as a provider alias:
# before
code = get_lang_code_by_provider_and_language("OpenAiGPT4o_2024_11_20_Provider", language)
# after — same string, same answer
code = client.get(
"/v1/resolve",
params={
"provider": "OpenAiGPT4o_2024_11_20_Provider",
"language": language.full_abbreviation(),
},
).json()["code"]
language accepts anything the console would have — a two-letter abbreviation, any region code, any casing.
What changed, deliberately
Ambiguous pairs now have one answer. 330 (provider, language) pairs had several codes and Django's .first() picked whichever row Postgres returned. Which code your job used was, in practice, arbitrary. Now it is fixed and documented — and every runner-up is still an inbound alias, so nothing that resolved before stops resolving. The full list of decisions is in data/seed/REPORT.md.
Broken codes are repaired. Cebuano's console code starts with a Cyrillic с, so get_language_by_code("ceb") never matched it. It matches here.
The code[:2] truncation is now a real lookup. The console ends with lang_region_list.code[:2] — the first two characters of an arbitrary region code. For ceb-latn-ph that produces ce, which is Chechen. This service walks to the actual base language row instead, so ceb stays ceb.
Per-model providers collapsed. OpenAI GPT 4o-2024-11-20 and OpenAI GPT 5-mini are both openai_api. Their console language tables were near-identical; where they differed, the newer model's choice won. See Providers and Vendors.
What did not change
Everything else. Every base language still resolves to its own code without a mapping, and every regional language with no mapping still falls back to its base — the same two rules the console applies, in the same order. See Resolution Ladder.
Resolve both languages in one call
A job needs a source and a target. Do not make two requests:
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)
See Resolve a whole job.
Suggested rollout
- Shadow. Call this service alongside the existing helper and log where the answers differ. Expect differences only on the 330 ambiguous pairs and on Cebuano.
- Switch reads. Replace the helper. Keep
service_nameas the provider argument — no other change needed. - Adopt canonical codes. Store
languagefrom the response instead of the raw inbound spelling. This is the step that makes records comparable; do it when convenient, not as a prerequisite. - Retire the console tables once no caller reads them.
Handling failure
The service is a dependency on the translation path. Two things make that safe:
- Cache. The catalog changes a few times a month. Caching
(provider, language) → codefor minutes is safe and removes the service from your hot path entirely. - Fall back to the input. If the call fails and you have no cached answer, sending the canonical code you already hold is what a
passthroughpolicy would have produced. Log it; do not fail the job.
Next
- Resolution Ladder — what the answers mean
- Endpoints Index — everything available