--- title: "Python SDK" subtitle: "AI translation with Python and Lingo.dev" --- ## Introduction The **Lingo.dev Python SDK** translates text, JSON objects, and chat conversations through an async API. It handles large payloads by automatically chunking content into optimal batch sizes, tracks progress for long-running translations, and supports glossaries for consistent terminology. ## Installation ### pip ```bash pip install lingodotdev ``` ### uv ```bash uv add lingodotdev ``` ## Quick translation Skip the context manager for one-off translations. These methods handle engine lifecycle automatically and default to fast mode, making them ideal for CLI tools and scripts. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev.engine import LingoDotDevEngine async def main(): api_key = os.environ["LINGODOTDEV_API_KEY"] # Translate text text_result = await LingoDotDevEngine.quick_translate( "Hello world", api_key=api_key, source_locale="en", target_locale="es" ) print(f"Text: {text_result}") # Translate object object_result = await LingoDotDevEngine.quick_translate( {"greeting": "Hello", "farewell": "Goodbye"}, api_key=api_key, source_locale="en", target_locale="fr" ) print(f"Object: {object_result}") asyncio.run(main()) ``` ## Basic usage The SDK requires an API key from Lingo.dev and uses async context managers. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: result = await engine.localize_text( "Welcome! We missed you.", {"source_locale": "en", "target_locale": "es"} ) print(result) asyncio.run(main()) ``` ## Text translation with progress Track translation progress with a callback. Even single text strings go through the chunker, enabling progress reporting for long texts and providing consistent behavior across all content types. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine def on_progress(percent: int): print(f"Progress: {percent}%") async def main(): api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: result = await engine.localize_text( "We sent a confirmation email.", {"source_locale": "en", "target_locale": "es"}, progress_callback=on_progress ) print(f"Result: {result}") asyncio.run(main()) ``` ## Object translation Translate nested dictionaries while preserving structure. The SDK recursively processes all string values regardless of depth. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): content = { "title": "Welcome", "cta": "Start your free trial", "footer": { "legal": "All rights reserved.", "help": "Need help?" } } api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: result = await engine.localize_object( content, {"source_locale": "en", "target_locale": "es"} ) print(result) asyncio.run(main()) ``` ## Batch translation to multiple languages Translate content to multiple target languages in a single call. Returns a list with one result per target locale, in the same order as requested. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: # Translate text to multiple languages text_results = await engine.batch_localize_text( "Welcome to our application", { "source_locale": "en", "target_locales": ["es", "fr", "de"], "fast": True } ) print(f"Text results: {text_results}") asyncio.run(main()) ``` ## Batch object translation Translate multiple objects concurrently in a single call. Each object is processed independently, making this ideal for localizing lists of records, product catalogs, or any collection of structured content. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): objects = [ {"title": "Getting Started", "description": "Learn the basics"}, {"title": "Advanced Usage", "description": "Deep dive into features"}, {"title": "API Reference", "description": "Complete method listing"}, ] api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: results = await engine.batch_localize_objects( objects, {"source_locale": "en", "target_locale": "es"} ) for result in results: print(result) asyncio.run(main()) ``` ## Batch object translation with quick method The quick batch method handles both text and objects. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev.engine import LingoDotDevEngine async def main(): api_key = os.environ["LINGODOTDEV_API_KEY"] results = await LingoDotDevEngine.quick_batch_translate( {"greeting": "Hello", "bye": "Goodbye"}, api_key=api_key, target_locales=["es", "fr", "de"], source_locale="en", fast=True, ) for locale, result in zip(["es", "fr", "de"], results): print(f"{locale}: {result}") asyncio.run(main()) ``` ## Chat translation Translate chat messages while preserving speaker names. Each message must have both "name" and "text" fields. Useful for localizing support conversations, chat logs, or dialogue systems without losing conversation structure. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): chat = [ {"name": "Alice", "text": "Hello everyone!"}, {"name": "Bob", "text": "How are you doing?"}, {"name": "Alice", "text": "Great, thanks for asking!"}, ] api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: result = await engine.localize_chat( chat, {"source_locale": "en", "target_locale": "es"} ) for message in result: print(f"{message['name']}: {message['text']}") asyncio.run(main()) ``` ## Sequential processing with progress Sequential mode enables detailed progress callbacks. The callback receives the source chunk and translated chunk for each batch processed, useful for debugging translation issues or showing detailed progress in UIs. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine def progress(percent: int, src_chunk: dict, out_chunk: dict): print(f"{percent}% complete - processed {len(src_chunk)} keys") async def main(): content = { "welcome": "Hello", "goodbye": "Farewell", "help": "Need assistance?" } api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: result = await engine.localize_object( content, {"source_locale": "en", "target_locale": "es"}, progress_callback=progress ) print(result) asyncio.run(main()) ``` ## Concurrent processing Process chunks in parallel for faster translation. This mode sacrifices progress tracking for speed, making it ideal for production workloads where throughput matters more than user feedback. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): content = { "header": {"title": "Welcome", "subtitle": "Get started"}, "body": {"intro": "Learn more", "details": "Full description"}, "footer": {"copyright": "2024", "contact": "Email us"} } api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: result = await engine.localize_object( content, {"source_locale": "en", "target_locale": "es"}, concurrent=True ) print(result) asyncio.run(main()) ``` ## Reference data Provide glossaries or previous translations to ensure consistency. Reference data is sent with every chunk to the API, so keep it reasonably sized. Use this for brand terms, technical vocabulary, or maintaining translation consistency across product updates. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): content = {"cta": "Start your free trial", "title": "Welcome"} reference = { "es": {"cta": "Comienza tu prueba gratuita"}, "fr": {"cta": "Commencez votre essai gratuit"}, } api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: result = await engine.localize_object( content, { "source_locale": "en", "target_locale": "es", "reference": reference, }, concurrent=True ) print(result) asyncio.run(main()) ``` ## Configuration Control batching behavior and API endpoints. The SDK splits large payloads based on key count and word count constraints, preventing API timeouts and improving reliability for large translation jobs. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): config = { "api_key": os.environ["LINGODOTDEV_API_KEY"], "api_url": "https://engine.lingo.dev", "batch_size": 25, # Items per chunk (1-250) "ideal_batch_item_size": 250, # Words per chunk (1-2500) } async with LingoDotDevEngine(config) as engine: result = await engine.localize_text( "Reset your password", {"source_locale": "en", "target_locale": "es", "fast": True} ) print(result) asyncio.run(main()) ``` ## Language detection Detect the language of a text string. Useful for automatically routing content to the correct translation pipeline or validating user input language. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: locale = await engine.recognize_locale("Guten Morgen") print(f"Detected language: {locale}") asyncio.run(main()) ``` ## API key introspection Check which account owns an API key. Returns None if authentication fails. Useful for debugging authentication issues or displaying account information in admin tools. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: user = await engine.whoami() if user: print(f"Authenticated as: {user}") else: print("Authentication failed") asyncio.run(main()) ``` ## Error handling The SDK raises ValueError for parameter issues and RuntimeError for network/server errors. Distinguish between user errors (ValueError) and infrastructure problems (RuntimeError) for appropriate retry logic. ```python # /// script # requires-python = ">=3.11" # dependencies = [ # "lingodotdev==1.3.0", # ] # /// import asyncio import os from lingodotdev import LingoDotDevEngine async def main(): try: api_key = os.environ["LINGODOTDEV_API_KEY"] async with LingoDotDevEngine({"api_key": api_key}) as engine: result = await engine.localize_text( "Hello", {"target_locale": "es"} ) print(result) except ValueError as e: print(f"Invalid parameters or bad request: {e}") except RuntimeError as e: print(f"Server or network error: {e}") asyncio.run(main()) ``` ## API reference ### Constructor | Parameter | Type | Default | Description | | ----------------------- | ----- | ---------------------------- | ------------------------ | | `api_key` | `str` | required | Lingo.dev API key | | `api_url` | `str` | `"https://engine.lingo.dev"` | API endpoint URL | | `batch_size` | `int` | `25` | Items per chunk (1–250) | | `ideal_batch_item_size` | `int` | `250` | Words per chunk (1–2500) | ### Instance methods | Method | Parameters | Returns | Description | | --------------------------------------------------------------- | ------------------------------------------------- | -------------- | ------------------------------------------------- | | `localize_text(text, params, progress_callback?)` | `text: str`, `params: dict` | `str` | Translate a single text string | | `localize_object(obj, params, progress_callback?, concurrent?)` | `obj: dict`, `params: dict` | `dict` | Translate a dictionary, preserving structure | | `localize_chat(chat, params, progress_callback?)` | `chat: list[dict]`, `params: dict` | `list[dict]` | Translate chat messages, preserving speaker names | | `batch_localize_text(text, params)` | `text: str`, `params: dict` with `target_locales` | `list[str]` | Translate text to multiple target locales at once | | `batch_localize_objects(objects, params)` | `objects: list[dict]`, `params: dict` | `list[dict]` | Translate multiple objects concurrently | | `recognize_locale(text)` | `text: str` | `str` | Detect the language of a text string | | `whoami()` | — | `dict \| None` | Get account info for the current API key | ### Class methods | Method | Parameters | Returns | Description | | ------------------------------------------------------------------------------------------ | ---------------------- | ------------- | --------------------------------------------- | | `quick_translate(content, api_key, target_locale, source_locale?, api_url?, fast?)` | `content: str \| dict` | `str \| dict` | One-off translation without context manager | | `quick_batch_translate(content, api_key, target_locales, source_locale?, api_url?, fast?)` | `content: str \| dict` | `list` | One-off batch translation to multiple locales | ### Localization params | Key | Type | Required | Description | | ---------------- | ----------- | --------- | -------------------------------------------------- | | `source_locale` | `str` | no | Source language code (auto-detected if omitted) | | `target_locale` | `str` | yes | Target language code | | `target_locales` | `list[str]` | for batch | List of target language codes | | `fast` | `bool` | no | Enable fast mode for quicker translations | | `reference` | `dict` | no | Glossary or reference translations for consistency |