Metadata-Version: 2.5
Name: lingva-sdk
Version: 0.1.0
Summary: Python client for the Lingva localization platform
License: SEE LICENSE IN ../../LICENSE.md
Requires-Python: >=3.11
Provides-Extra: dev
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Provides-Extra: http
Requires-Dist: httpx>=0.27; extra == 'http'
Description-Content-Type: text/markdown

# lingva — Python SDK

Python client for the [Lingva](https://lingva.dev) localization platform.

**Requires Python 3.11+.**

> This is a preview package. It follows the same conformance contract as the Swift, Kotlin, and Flutter SDKs but is not yet published to PyPI.

---

## Install

```bash
# From the monorepo root (editable install)
pip install -e sdks/python

# With async HTTP support (httpx)
pip install -e "sdks/python[http]"
```

Once published:

```bash
pip install lingva-sdk
pip install "lingva-sdk[http]"   # adds httpx for async delivery
```

---

## Quickstart

### Load from a local bundle file

```python
from lingva import LingvaClient

client = LingvaClient.from_file(".lingva/translations/en.bundle.json")

print(client.t("actions.continue"))           # Continue
print(client.t("welcome.title", name="Alice")) # Welcome, Alice.
```

### Load from CDN (async)

```python
import asyncio
from lingva import LingvaClient, LingvaDeliveryTarget

target = LingvaDeliveryTarget(
    base_url="https://api.lingva.dev",
    project_id="my-project",
    environment="production",
)

async def main():
    client = await LingvaClient.from_url(target, locale="fr", fallback_locale="en")
    print(client.t("welcome.title", name="Alice"))

asyncio.run(main())
```

### Load from CDN (synchronous)

```python
from lingva import LingvaClient, LingvaDeliveryTarget

target = LingvaDeliveryTarget(
    base_url="https://api.lingva.dev",
    project_id="my-project",
    environment="production",
)

client = LingvaClient.from_url_sync(target, locale="fr", fallback_locale="en")
print(client.t("welcome.title", name="Alice"))
```

---

## API

### `LingvaClient`

| Method / Property | Description |
|---|---|
| `LingvaClient.from_bundle(bundle)` | Create from a parsed dict |
| `LingvaClient.from_file(path, *, fallback_path=None)` | Load from filesystem |
| `LingvaClient.from_url_sync(target, locale, ...)` | Synchronous HTTP fetch |
| `await LingvaClient.from_url(target, locale, ...)` | Async HTTP fetch (requires `lingva[http]`) |
| `.t(key, **variables)` | Translate a key with optional `{varname}` substitution |
| `.has(key)` | Check if a key exists |
| `.locale` | Active locale string |
| `.fallback_locale` | Fallback locale string or `None` |
| `.bundle()` | Raw bundle dict (for last-valid caching) |

### `LingvaDeliveryTarget`

```python
LingvaDeliveryTarget(
    base_url="https://api.lingva.dev",
    project_id="my-project",
    environment="production",          # default
    uri_template="...",                # optional custom path template
)
target.resolve("fr")
# -> "https://api.lingva.dev/bundles/my-project/production/latest/fr.bundle.json"
```

---

## Bundle schema

The SDK reads schemaVersion 1 bundles. Variables use `{varname}` syntax. Unknown variables pass through unchanged.

```json
{
  "schemaVersion": 1,
  "locale": "en",
  "fallbackLocale": "en",
  "fallbackKeys": [],
  "messages": {
    "actions.continue": "Continue",
    "welcome.title": "Welcome, {name}."
  }
}
```
