lokex

module
v2.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2026 License: BSD-3-Clause

README

Lokex

GitHub Release CI Code Coverage Maintainability

lokex is a Go client for uploading and downloading translations from Lokalise. It provides a thin wrapper around the Lokalise API with retry/backoff, async polling, safe unzipping, and strict upload validation.

Lokex also has a cross-platform CLI version: lokex-cli.

Installation

go get github.com/bodrovis/lokex/v2

Usage

Create a client
import (
    "log"
    "time"

    "github.com/bodrovis/lokex/v2/client"
)

cli, err := client.NewClient("YOUR_API_TOKEN", "LOKALISE_PROJECT_ID", client.WithBackoff(
    1*time.Second,  // min backoff
    5*time.Second,  // max backoff
))
if err != nil {
    log.Fatal(err)
}

By default, the base URL is https://api.lokalise.com/api2/. You can override it with client.WithBaseURL("...") if needed for testing.

Downloads

Download and unzip a translation bundle into ./locales:

import (
    "github.com/bodrovis/lokex/v2/client/download"
)

downloader := download.NewDownloader(cli)

ctx, cancel := context.WithTimeout(context.Background(), 150*time.Second)
defer cancel()

// call DownloadAsync() for the async download flow
url, err := downloader.Download(ctx, "./locales", download.DownloadParams{
    "format": "json",
    // other request params...
})
if err != nil {
    log.Fatal(err)
}

fmt.Println("Bundle downloaded from:", url)

Features:

  • Retries on rate limiting errors, 5xx, or truncated/corrupted ZIPs.
  • Rejects zip-slip, symlinks, and oversized bundles.
  • Validates content length and zip structure before unzipping.
Uploads

Upload a JSON file for the English (en) locale:

import (
    "github.com/bodrovis/lokex/v2/client/upload"
)

uploader := upload.NewUploader(cli)

fp := filepath.Join(dir, "en.json")

ctx, cancel := context.WithTimeout(context.Background(), 150*time.Second)
defer cancel()

// srcPath (3rd argument) is optional:
// - if srcPath == "" -> uploader reads from params["filename"]
// - if srcPath != "" -> uploader reads file bytes from srcPath,
//   but still sends params["filename"] to Lokalise API as the remote filename.
pid, err := uploader.Upload(ctx, upload.UploadParams{
	"filename": fp,      // sent to Lokalise (remote filename)
	"lang_iso": "en",
	// other request params...
}, "", true) // srcPath="", poll=true (pass false to skip polling)
if err != nil {
	log.Fatal(err)
}

fmt.Println("Upload finished with process ID:", pid)

Features:

  • Validates filename and ensures it points to a real file (not a directory).
  • Auto-encodes file contents to base64 unless data is provided.
  • Accepts data as a pre-encoded string or raw []byte.
  • Polls the process until it finishes (unless polling is disabled).
Batch Uploads

Upload several locale files in one call:

import (
    "context"
    "fmt"
    "log"
    "path/filepath"
    "time"

    "github.com/bodrovis/lokex/v2/client/upload"
)

uploader := upload.NewUploader(cli)

dir := "/path/to/locales"

items := []upload.BatchUploadItem{
    {
        Params: upload.UploadParams{
            "filename": filepath.Join(dir, "en.json"),
            "lang_iso": "en",
        },
        // SrcPath omitted:
        // uploader reads bytes from Params["filename"]
    },
    {
        Params: upload.UploadParams{
            "filename": "locales/%LANG_ISO%.json", // remote filename sent to Lokalise
            "lang_iso": "de",
        },
        SrcPath: filepath.Join(dir, "de.json"), // local file to read bytes from
    },
    {
        Params: upload.UploadParams{
            "filename": "locales/%LANG_ISO%.json",
            "lang_iso": "fr",
        },
        SrcPath: filepath.Join(dir, "fr.json"),
    },
}

ctx, cancel := context.WithTimeout(context.Background(), 150*time.Second)
defer cancel()

// poll=true:
// - starts all uploads
// - then polls all successfully started processes together
//
// poll=false:
// - returns right after kickoff with per-item process IDs/errors
result, err := uploader.UploadBatch(ctx, items, true)
if err != nil {
    log.Fatal(err) // fatal batch-level error only
}

for _, item := range result.Items {
    if item.Err != nil {
        fmt.Printf("upload failed: index=%d src=%q err=%v\n", item.Index, item.SrcPath, item.Err)
        continue
    }

    fmt.Printf("upload finished: index=%d src=%q process_id=%s\n", item.Index, item.SrcPath, item.ProcessID)
}

if result.HasErrors() {
    fmt.Println("some uploads failed")
}

fmt.Printf("successful process IDs: %#v\n", result.SuccessfulProcessIDs())

UploadBatch returns:

  • BatchUploadResult — per-item results, always in the same order as the input slice
  • error — only for fatal batch-level problems such as a nil uploader/client or an already-cancelled context

Each BatchUploadResultItem contains:

  • Index — original position in the input slice
  • SrcPath — local source path used for that item
  • ProcessID — Lokalise process ID for successful kickoff/completion
  • Err — per-item error; does not fail the whole batch

Notes:

  • Upload kickoff runs with a maximum concurrency of 6 files at a time
  • Each file still uses the same single-upload logic internally, including retries
  • Partial success is supported: one failed file does not discard successful ones
  • SrcPath is optional per item:
    • if SrcPath == "", uploader reads bytes from Params["filename"]
    • if SrcPath != "", uploader reads bytes from SrcPath, but still sends Params["filename"] to Lokalise as the remote filename

Testing

Unit tests use httpmock. Integration tests hit the real Lokalise API and require credentials in .env.

Run unit tests only:

go test ./... -v -short

Run with full integration tests:

go test ./... -v

License

(c) Ilya Krukowski. Licensed under BSD-3-Clause

Directories

Path Synopsis
Package client provides shared Lokalise client state and convenience helpers used by higher-level upload, download, and background workflows.
Package client provides shared Lokalise client state and convenience helpers used by higher-level upload, download, and background workflows.
download
Package download provides a downloader for Lokalise export bundles.
Package download provides a downloader for Lokalise export bundles.
upload
Package upload provides an uploader for Lokalise file imports.
Package upload provides an uploader for Lokalise file imports.
internal
apierr
Package apierr defines typed API errors used across lokex.
Package apierr defines typed API errors used across lokex.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL