Skip to Content
FeaturesModulesLLM IntegrationTranslation

Translation

DjangoTranslator is the translation orchestrator built into django_llm. It uses the configured LLM client (OpenAI or OpenRouter) to translate plain text and nested JSON objects, with automatic language detection, a two-level cache, and per-session statistics.

Quick Start

The easiest way to translate is through the module-level convenience functions:

from django_cfg.modules.django_llm import translate_text, translate_json # Translate a string result = translate_text("Привет мир", target_language="en") # "Hello world" # Translate a nested dict data = translate_json( {"title": "Привет", "body": "Добро пожаловать"}, target_language="en", ) # {"title": "Hello", "body": "Welcome"}

These helpers instantiate DjangoTranslator automatically using the API key from Django config.

Using DjangoTranslator Directly

from django_cfg.modules.django_llm.features.translator import DjangoTranslator from django_cfg.modules.django_llm.client import LLMClient # Auto-configure from Django config translator = DjangoTranslator() # Or pass a client explicitly client = LLMClient(apikey_openrouter="sk-or-v1-...") translator = DjangoTranslator(client=client)

Check Configuration

if translator.is_configured: print("Ready to translate")

is_configured returns True when a client was passed directly or when config.llm.api_key is set.

Translating Text

# Auto-detect source language translated = translator.translate( text="안녕하세요", target_language="en", ) # Specify source language explicitly translated = translator.translate( text="Bonjour le monde", target_language="en", source_language="fr", ) # Override the model and temperature for this call translated = translator.translate( text="Hello", target_language="es", model="openai/gpt-4o", temperature=0.0, ) # Suppress exceptions — return original text on failure translated = translator.translate( text="...", target_language="ko", fail_silently=True, )

translate() Parameters

ParameterTypeDefaultDescription
textstrText to translate
target_languagestr"en"BCP-47 language code
source_languagestr"auto"Source language code, or "auto" for detection
fail_silentlyboolFalseReturn original text instead of raising on failure
modelstr | NoneNoneOverride the LLM model for this request
temperaturefloat | NoneNoneOverride sampling temperature (default 0.1)

Translating JSON Objects

translate_json traverses a dict recursively, collecting all string values that need translation, sends them to the LLM in a single batched request, caches each translated string individually, and then reconstructs the original structure.

product = { "id": 42, "title": "노트북", "description": "가볍고 빠른 울트라북", "specs": { "cpu": "Intel i7", "storage": "512GB SSD" }, "tags": ["전자제품", "컴퓨터"], } translated = translator.translate_json( data=product, target_language="en", source_language="auto", ) # { # "id": 42, # "title": "Laptop", # "description": "A light and fast ultrabook", # "specs": {"cpu": "Intel i7", "storage": "512GB SSD"}, # "tags": ["electronics", "computer"], # }

What Gets Translated

  • String values in dicts and lists (translated by the LLM)
  • Nested dicts and lists (traversed recursively)

What Is Never Translated

  • JSON keys (always preserved as-is)
  • URLs (http://..., https://..., www.)
  • File paths containing /
  • Pure numbers
  • ALL-CAPS identifiers (e.g., SKIP_TRANSLATION, USD)
  • Empty strings

translate_json() Parameters

ParameterTypeDefaultDescription
datadictJSON object to translate
target_languagestr"en"Target language code
source_languagestr"auto"Source language, or "auto"
fail_silentlyboolFalseReturn original data on failure
modelstr | NoneNoneLLM model override
temperaturefloat | NoneNoneTemperature override (default 0.1)

Language Detection

Language detection happens in two stages, handled by two separate detector classes.

Script Detector (ScriptDetector)

The primary detector, used for translate(). Identifies language by Unicode script ranges — no external library required.

ScriptDetected Language
Hangul (AC00–D7AF)ko
Hiragana / Katakana (3040–30FF)ja
Other CJK ideographszh
Cyrillic (0400–04FF)ru
Everything elseen (default)
lang = translator.detect_language("안녕하세요") # "ko" lang = translator.detect_language("こんにちは") # "ja" lang = translator.detect_language("Привет") # "ru" lang = translator.detect_language("Hello") # "en"

Language Detector (LanguageDetector)

A dictionary-based detector used by translate_json. Counts common words for English, Russian, Spanish, and Portuguese, then picks the language with the most matches. Falls back to "en" when no matches are found.

# Used internally when source_language="auto" in translate_json

Check If Translation Is Needed

needed = translator.needs_translation( text="Hello", source_language="en", target_language="en", # Same language → False )

Supported Languages

Both the prompt builder and text utilities recognise these codes:

CodeLanguage
enEnglish
ruRussian
koKorean
zhChinese
jaJapanese
esSpanish
frFrench
deGerman
itItalian
ptPortuguese
arArabic
hiHindi
trTurkish
plPolish
ukUkrainian
beBelarusian
kkKazakh

Any other BCP-47 code is passed through to the LLM prompt as-is.

Caching

DjangoTranslator uses a two-level cache managed by TranslationCacheManager:

LevelBackendTTL
Memorycachetools.TTLCache (1 000 entries max)24 hours
FileJSON files on disk, one per language pairPersistent

Cache files are stored at:

<django_cfg package dir>/.cache/llm_translate/<source>→<target>.json

For example, ko→en.json holds all Korean-to-English translations.

Cache Lookup Order

  1. Check in-memory TTL cache (<source>→<target>:<md5_of_text>)
  2. Load the corresponding file cache and promote to memory
  3. On miss, call the LLM and write to both layers

translate_json Partial Caching

For JSON translation, only strings that are not already cached are sent to the LLM. Cached translations are merged with the fresh LLM response before reconstructing the object, so re-translating the same product catalogue is nearly free after the first call.

Clearing the Cache

# Clear all caches translator.clear_cache() # Clear a specific language pair via the cache manager translator.translation_cache.clear(source_lang="ko", target_lang="en") # Inspect cache state stats = translator.translation_cache.get_stats() print(stats["memory_cache_size"]) # entries in memory print(stats["language_pairs"]) # list of {pair, translations, file_size}

Statistics

StatsTracker records per-session counters that accumulate in memory.

stats = translator.get_stats() # { # "total_translations": 42, # "successful_translations": 41, # "failed_translations": 1, # "cache_hits": 38, # "cache_misses": 4, # "total_tokens_used": 12800, # "total_cost_usd": 0.0032, # "language_pairs": {"ko-en": 30, "ru-en": 12} # }
FieldDescription
total_translationsTotal translate() calls
successful_translationsCalls that returned a translated string
failed_translationsCalls that raised or returned original text
cache_hitsServed directly from cache
cache_missesRequired an LLM API call
total_tokens_usedSum of tokens_used from LLM responses
total_cost_usdSum of cost_usd from LLM responses
language_pairsCount per "<source>-<target>" pair

Configuration Info

info = translator.get_config_info() # { # "configured": True, # "provider": "openrouter", # "cache_size": 14, # "client_info": {...}, # "supported_languages": ["en", "ru", "ko", ...] # }

Sending Translation Alerts

The class method send_translation_alert sends an HTML-formatted message to the configured Telegram chat (via DjangoTelegram). It is a fire-and-forget notification — errors are logged but never re-raised.

DjangoTranslator.send_translation_alert( message="High translation failure rate detected", context={"failure_rate": "12%", "language_pair": "ko→en"}, )

Error Handling

TranslationError is the base exception for all translation failures:

from django_cfg.modules.django_llm.features.translator import TranslationError try: result = translator.translate("Hello", target_language="fr") except TranslationError as e: print(f"Translation failed: {e}")

Pass fail_silently=True to suppress TranslationError and return the original input instead.

TAGS: translation, llm, language-detection, caching, json

Last updated on