Python SDK
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
pip install lingodotdev
uv
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.
# /// 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.
# /// 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.
# /// 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.
# /// 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.
# /// 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
The quick batch method handles both text and objects.
# /// 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.
# /// 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.
# /// 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.
# /// 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.
# /// 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.
# /// 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.
# /// 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.
# /// 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.
# /// 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())