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

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.

# /// 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.

# /// 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())

API reference

Constructor

ParameterTypeDefaultDescription
api_keystrrequiredLingo.dev API key
api_urlstr"https://engine.lingo.dev"API endpoint URL
batch_sizeint25Items per chunk (1–250)
ideal_batch_item_sizeint250Words per chunk (1–2500)

Instance methods

MethodParametersReturnsDescription
localize_text(text, params, progress_callback?)text: str, params: dictstrTranslate a single text string
localize_object(obj, params, progress_callback?, concurrent?)obj: dict, params: dictdictTranslate a dictionary, preserving structure
localize_chat(chat, params, progress_callback?)chat: list[dict], params: dictlist[dict]Translate chat messages, preserving speaker names
batch_localize_text(text, params)text: str, params: dict with target_localeslist[str]Translate text to multiple target locales at once
batch_localize_objects(objects, params)objects: list[dict], params: dictlist[dict]Translate multiple objects concurrently
recognize_locale(text)text: strstrDetect the language of a text string
whoami()dict | NoneGet account info for the current API key

Class methods

MethodParametersReturnsDescription
quick_translate(content, api_key, target_locale, source_locale?, api_url?, fast?)content: str | dictstr | dictOne-off translation without context manager
quick_batch_translate(content, api_key, target_locales, source_locale?, api_url?, fast?)content: str | dictlistOne-off batch translation to multiple locales

Localization params

KeyTypeRequiredDescription
source_localestrnoSource language code (auto-detected if omitted)
target_localestryesTarget language code
target_localeslist[str]for batchList of target language codes
fastboolnoEnable fast mode for quicker translations
referencedictnoGlossary or reference translations for consistency