Python SDK (polylingo)

Official Python client for the PolyLingo REST API. It uses httpx and provides both sync and async clients with the same method names.

For raw HTTP details, see API reference.


Installation

pip install polylingo

Python: >= 3.9


Sync client

import os
import polylingo

client = polylingo.PolyLingo(
    api_key=os.environ["POLYLINGO_API_KEY"],
    base_url="https://api.usepolylingo.com/v1",  # optional; default shown
    timeout=120.0,  # optional; seconds per request (default 120)
)

result = client.translate(content="# Hello", targets=["es", "fr"], format="markdown")
print(result["translations"]["es"])

client.close()

Context manager:

with polylingo.PolyLingo(api_key="...") as client:
    print(client.languages())
ArgumentRequiredDescription
api_keyYesAPI key (Authorization: Bearer …).
base_urlNoAPI prefix including /v1. Default https://api.usepolylingo.com/v1.
timeoutNohttpx timeout in seconds. Default 120.0.

Async client

import polylingo

async with polylingo.AsyncPolyLingo(api_key="...") as client:
    r = await client.translate(content="Hi", targets=["de"])

Use await client.aclose() if not using async with.

Method names match the sync client; all network methods are async def.


Methods (sync and async)

health() / await health()

GET /health

h = client.health()
# async: h = await client.health()

languages() / await languages()

GET /languages

data = client.languages()
langs = data["languages"]

translate(...)

POST /translate

r = client.translate(
    content="# Hello",
    targets=["es", "fr"],
    format="markdown",  # optional
    source="en",        # optional
    model="standard",   # optional: "standard" | "advanced"
)
r["translations"]["es"]
r["usage"]["total_tokens"]

batch(...)

POST /translate/batch

b = client.batch(
    items=[
        {"id": "a", "content": "Hello"},
        {"id": "b", "content": "## Title", "format": "markdown"},
    ],
    targets=["de"],
)
b["results"][0]["translations"]["de"]

usage() / await usage()

GET /usage

u = client.usage()

Jobs (client.jobs)

create / await create

POST /jobs. Returns the 202 body (job_id, status, …).

job = client.jobs.create(content=long_md, targets=["de", "fr"], format="markdown")
# kwargs also accepted: client.jobs.create(**{"content": ..., "targets": [...]})

get(job_id) / await get(job_id)

GET /jobs/:id. When status == "completed", responses include translations and usage at the top level.

translate(...) (convenience)

Polls until completed or failed, or until time runs out.

done = client.jobs.translate(
    content=long_md,
    targets=["de", "fr", "es"],
    format="markdown",
    poll_interval=10.0,   # seconds between polls; default 5.0
    timeout=600.0,        # **total** seconds budget; default 1200 (20 min)
    on_progress=lambda pos: print(f"Queue: {pos}"),
)
done["translations"]["de"]

Async:

done = await client.jobs.translate(
    content=long_md,
    targets=["de"],
    poll_interval=2.0,
    timeout=300.0,
)

API statuses: pending, processing, completed, failed.


Exceptions

ClassWhen
polylingo.PolyLingoErrorBase. status, error, args[0] message.
polylingo.AuthErrorHTTP 401.
polylingo.RateLimitErrorHTTP 429. retry_after may be set (seconds).
polylingo.JobFailedErrorFailed job, bad completed payload, or polling timeout. Includes job_id.
import polylingo

try:
    client.translate(content="x", targets=["es"])
except polylingo.AuthError as e:
    print(e.status, e.error)
except polylingo.RateLimitError as e:
    print(e.retry_after)
except polylingo.JobFailedError as e:
    print(e.job_id)
except polylingo.PolyLingoError as e:
    print(e.status, e.error)

Async jobs pattern (summary)

  1. Manual: jobs.create → loop jobs.get until terminal state.
  2. Helper: jobs.translate with poll_interval, timeout, and optional on_progress.

Prefer jobs for very large content where synchronous translate might hit client or server timeouts.


Types

The package ships py.typed. Response objects are plain dict values aligned with the API; use TypedDict-style annotations in your code if desired.


Changelog

0.1.2

  • Maintenance: default API base URL is https://api.usepolylingo.com/v1.

0.1.0

  • Initial release: sync PolyLingo, async AsyncPolyLingo, full endpoint coverage including jobs.translate polling helper.
Python SDK | PolyLingo docs | PolyLingo