forjio-locavello
Typed Python client for the locavello.forjio.com localization REST API.
pip install forjio-locavello
from forjio_locavello import LocavelloClient, paginate
# Bearer token from api_key= or the LOCAVELLO_API_KEY env var — use an
# lv_live_... API key from Dashboard -> Settings -> API keys.
client = LocavelloClient(api_key="lv_live_xxx")
# Projects — create, browse, locales + namespaces
project = client.projects.create(slug="marketing-site", name="Marketing Site")
page = client.projects.list(limit=20) # {"data", "cursor", "has_more"}
detail = client.projects.get(project["id"]) # + locale stats, namespaces, lastRelease
client.projects.add_locale(project["id"], tag="id", fallback="en")
client.projects.update_locale(project["id"], "id", enabled=True)
stats = client.projects.locales(project["id"]) # plain array, not a Page
client.projects.add_namespace(project["id"], name="checkout", review_policy="gated")
# Keys — bulk-sync source strings (max 2000 per request), then browse
result = client.keys.upsert(
project["id"],
keys=[
{"name": "cta.title", "sourceText": "Get started"},
{"namespace": "checkout", "name": "pay.button", "sourceText": "Pay now", "maxLength": 12},
],
prune=True,
) # {"created", "updated", "archived"}
for key in paginate(lambda c: client.keys.list(project["id"], status="missing", cursor=c)):
print(key["name"])
# Translations — set values, work the review queue
client.translations.set("key_...", "id", value="Mulai sekarang", status="needs_review")
queue = client.translations.review_queue(project["id"], locale="id")
client.translations.approve(queue["data"][0]["id"])
client.translations.reject("trn_...", reason="Wrong tone")
# Releases — publish per locale, pull catalogs, gate CI
release = client.releases.publish(project["id"], locale="id")
bundle = client.releases.pull(project["id"]) # all released catalogs + fallbacks
check = client.releases.check(project["id"]) # {"ok", "errors", "warnings", "stats"}
diff = client.releases.diff(release["id"], "rel_previous")
# Jobs — machine translate + site crawl
job = client.jobs.translate(project["id"], locale="id")
job = client.jobs.get(job["id"]) # poll: queued | running | done | failed
client.jobs.crawl(project["id"]) # proxy-mode projects
pages = client.jobs.pages(project["id"])
# Glossary + translation memory
client.glossary.create(term="Forjio") # no translation = do-not-translate
client.glossary.create(term="checkout", locale="id", translation="pembayaran")
tm = client.tm.suggest(text="Get started", target="id") # {"exact", "fuzzy"}
hits = client.tm.search(q="started", target="id")
# API keys + billing
minted = client.api_keys.create(name="ci") # plaintext shown once
info = client.billing.get()
out = client.billing.checkout("pro") # redirect the browser to out["hostedUrl"]
# Public surface — no api key required, never sends Authorization
preview = client.public.preview(url="https://example.com", target_locale="id")
result = client.public.preview_result(preview["previewId"])
catalog = client.public.catalog(project["id"], locale="id")
Endpoints covered
| Namespace | Methods |
|---|---|
projects |
create, list, get, update (nullable site_url), add_locale, update_locale, locales, add_namespace, update_namespace |
keys |
upsert (bulk sync + prune), list (namespace / q / locale / status / archived / limit / cursor) |
translations |
update_key, set (value + status + author, returns lengthWarning), review_queue, approve, reject |
releases |
publish, list, get, pull (draft / pseudo), check, diff |
jobs |
translate, crawl, pages, list, get |
glossary |
create, list, delete |
tm |
suggest(text, target), search(q, target) |
api_keys |
create, list, revoke |
billing |
get (subscription + usage + tier table), checkout(tier) -> hosted checkout URL |
public |
preview, preview_result, catalog (no api key) |
List methods return a Page dict {"data", "cursor", "has_more"};
paginate(fetch) walks every page of any list method. Idempotent GETs
are retried automatically (max 2) on HTTP 429/502/503/504 and network
errors with exponential backoff from retry_base_ms.
Errors raise LocavelloError carrying the API envelope's error.code
(NOT_FOUND, VALIDATION_ERROR, AUTH_REQUIRED, ...), the HTTP
status, and the meta.requestId.
Family
Sister to:
@forjio/locavello(JS/TS)hachimi-cat/locavello-go(Go)
Metadata
Release files for forjio-locavello 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| forjio_locavello-0.1.1.tar.gz | 17.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| forjio_locavello-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.9 kB
Release files / forjio_locavello-0.1.1.tar.gz
| Download URL | forjio_locavello-0.1.1.tar.gz |
|---|---|
| Size | 17.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b9251691201e2f568e53a49d046b36ad023b5b2e044ad0464ce65c81ba6b148d
|
|
BLAKE2b-256 checksum How to use checksums |
f4ad2035f5dab4e0a0763db9b9d828b302a7a489cdc77ccef0b1a1a7dcabfbb7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / forjio_locavello-0.1.1-py3-none-any.whl
| Download URL | forjio_locavello-0.1.1-py3-none-any.whl |
|---|---|
| Size | 15.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d3a28a967e3ef5d7b7b414430f7350828606b630e8253ab87abc03d1b63462ee
|
|
BLAKE2b-256 checksum How to use checksums |
87f120999279496075fb7506cc52be96a50233e328c4760857c51b3bd2f5c450
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|