
PolyLingo SDKを使ってJavaから構造化コンテンツを翻訳する
By Robert
PolyLingo SDKを使ったJavaからの構造化コンテンツの翻訳
PolyLingo Java SDKは現在Maven Centralで利用可能です。同期翻訳、バッチリクエスト、ポーリング付き非同期ジョブ、すべてのユーティリティエンドポイントを含む完全なPolyLingo APIをカバーしています。Java 11以降が必要で、標準ライブラリのHTTPクライアントを使用し、ランタイム依存はJSON用のJacksonが1つだけです。
インストール
Maven
<dependency>
<groupId>com.usepolylingo</groupId>
<artifactId>polylingo</artifactId>
<version>0.1.0</version>
</dependency>
Gradle
implementation 'com.usepolylingo:polylingo:0.1.0'
追加のHTTPクライアント依存は不要です。SDKはJava 11標準ライブラリのjava.net.http.HttpClientを使用します。
クライアントのセットアップ
import com.usepolylingo.polylingo.PolyLingo;
PolyLingo client = PolyLingo.builder()
.apiKey(System.getenv("POLYLINGO_API_KEY"))
.build();
オプションのビルダーパラメータが2つあります:
PolyLingo client = PolyLingo.builder()
.apiKey(System.getenv("POLYLINGO_API_KEY"))
.baseUrl("https://api.usepolylingo.com/v1") // デフォルト。セルフホスト環境用に上書き可能
.timeout(Duration.ofSeconds(30)) // デフォルトは120秒
.build();
APIキーは環境変数に保存してください。コードにハードコーディングしたりバージョン管理にコミットしたりしないでください。
SDKはビルダーパターンを全面的に採用しています。位置引数のコンストラクタはなく、必須フィールドの順序もありません。すべてのオプションフィールドには妥当なデフォルトがあるため、変更が必要な部分だけ設定すればよいです。
コンテンツの翻訳
単一リクエスト
import com.usepolylingo.polylingo.types.TranslateParams;
import com.usepolylingo.polylingo.types.TranslateResult;
TranslateResult result = client.translate(
TranslateParams.builder()
.content("Hello, world!")
.targets(List.of("es", "fr", "de"))
.build()
);
result.getTranslations().forEach((lang, text) ->
System.out.println(lang + ": " + text)
);
// es: ¡Hola, mundo!
// fr: Bonjour le monde !
// de: Hallo Welt!
TranslateParamsビルダーはcontentとtargetsを必須フィールドとして受け入れます。オプションパラメータにはformat(plain、markdown、json、htmlのいずれか。省略時は自動検出)、言語ヒントとしてのsource、standard(デフォルト)またはadvancedのmodelがあります。
フォーマットの保持はPolyLingo APIの他の部分と同様に動作します。jsonコンテンツでは文字列値のみが翻訳され、キーやネスト、非文字列型はそのままです。markdownでは見出しは見出しのままで、コードブロックはそのまま保持されます。htmlではタグと属性が保持され、テキストノードのみが翻訳されます。
JSONロケールファイルの翻訳
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.file.Files;
import java.nio.file.Path;
ObjectMapper mapper = new ObjectMapper();
String sourceJson = Files.readString(Path.of("messages/en.json"));
TranslateResult result = client.translate(
TranslateParams.builder()
.content(sourceJson)
.format("json")
.targets(List.of("fr", "de", "ja"))
.build()
);
result.getTranslations().forEach((locale, translated) -> {
try {
Object parsed = mapper.readValue(translated, Object.class);
String pretty = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(parsed);
Files.writeString(Path.of("messages/" + locale + ".json"), pretty);
System.out.println("Wrote messages/" + locale + ".json");
} catch (Exception e) {
throw new RuntimeException(e);
}
});
1つのリクエストで3つのロケールすべてを処理します。すべての出力ファイルでキーはソースと同一です。
バッチリクエスト
1回のリクエストで最大100件のコンテンツアイテムを送信できます。各アイテムには独自のidとオプションのformatがあります:
import com.usepolylingo.polylingo.types.BatchParams;
import com.usepolylingo.polylingo.types.BatchItem;
import com.usepolylingo.polylingo.types.BatchResult;
BatchResult result = client.batch(
BatchParams.builder()
.targets(List.of("es", "ja"))
.addItem(BatchItem.builder().id("title").content("Welcome").build())
.addItem(BatchItem.builder().id("body").content("Get started today.").build())
.build()
);
for (BatchItemResult item : result.getResults()) {
System.out.println(item.getId() + ": " + item.getTranslations());
}
すべてのアイテムは同じtargetsリストを共有します。割り当てたidはレスポンスで保持されるため、順序に依存せずに結果を元のデータにマッピングできます。
非同期ジョブ
長いドキュメントや大規模な翻訳負荷の場合、ジョブAPIはリクエストを受け取り、ジョブIDを即座に返し、結果をポーリングできます。SDKはこれを2つの方法で扱います。
完了までポーリングする1回の呼び出し
import com.usepolylingo.polylingo.types.JobsTranslateParams;
TranslateResult result = client.jobs().translate(
JobsTranslateParams.builder()
.content(longArticleText)
.targets(List.of("fr", "de", "ja", "zh"))
.pollInterval(Duration.ofSeconds(3))
.timeout(Duration.ofMinutes(10))
.onProgress(queuePosition ->
System.out.println("Queue position: " + queuePosition))
.build()
);
result.getTranslations().forEach((lang, text) ->
System.out.println(lang + ": " + text.substring(0, 100) + "...")
);
onProgressコールバックは各ポーリング時に現在のキュー位置(整数)で呼ばれます。APIが返さない場合はnullです。進捗のログやUIの更新に使います。
手動でキューに入れてポーリング
import com.usepolylingo.polylingo.types.CreateJobParams;
import com.usepolylingo.polylingo.types.Job;
Job job = client.jobs().create(
CreateJobParams.builder()
.content("Translate this.")
.targets(List.of("es"))
.build()
);
// 自分でポーリング
Job status = client.jobs().get(job.getJobId());
System.out.println(status.getStatus()); // pending / processing / completed / failed
ユーティリティエンドポイント
// APIのヘルスチェック(APIキー不要)
HealthResponse health = client.health();
System.out.println(health.getStatus()); // "ok"
// 対応言語一覧(APIキー不要)
LanguagesResponse langs = client.languages();
langs.getLanguages().forEach(l ->
System.out.println(l.getCode() + " — " + l.getName())
);
// 現在の請求月のトークン使用状況を確認
UsageResponse usage = client.usage();
System.out.println("Tokens used: " + usage.getUsage().getTokensUsed());
System.out.println("Tokens remaining: " + usage.getUsage().getTokensRemaining());
エラーハンドリング
すべての例外はチェックされません。強制的なthrows宣言もなく、チェック例外のチェーンを解く必要もありません:
import com.usepolylingo.polylingo.errors.*;
try {
TranslateResult result = client.translate(
TranslateParams.builder()
.content("# Hello")
.targets(List.of("es", "fr"))
.format("markdown")
.build()
);
} catch (AuthException e) {
// HTTP 401 — 無効、欠落、または取り消されたAPIキー
System.out.println("Auth failed: " + e.getError());
} catch (RateLimitException e) {
// HTTP 429 — 1分あたりの制限に達した
e.getRetryAfter().ifPresent(s ->
System.out.println("Retry after: " + s + "s")
);
} catch (JobFailedException e) {
// 非同期ジョブが失敗の終端状態に達したか、ポーリングがタイムアウトした
System.out.println("Job " + e.getJobId() + " failed: " + e.getError());
} catch (PolyLingoException e) {
// その他すべてのAPIエラー
System.out.println(e.getStatus() + ": " + e.getMessage());
}
RateLimitException.getRetryAfter()はOptional<Integer>を返します。APIが秒数を含む場合はその値があり、そうでなければ空です。JobFailedException.getJobId()は失敗したジョブのIDを返し、ログ記録やリトライロジックに使えます。
デザインノート
SDKを評価する際に知っておくべきいくつかの決定事項:
同期API。 すべてのメソッドはブロックし、結果を直接返します。FutureもCompletableFutureもリアクティブストリームもありません。ジョブのポーリングが重い負荷向けのSDKの非同期機能です — ジョブを送信し、SDKがスレッド上でポーリングし、キュー位置の更新に応じてonProgressコールバックを呼びます。
ビルダーパターンを全面採用。 すべてのパラメータオブジェクトはビルダーを使います。位置引数のコンストラクタがないため、引数の順序を推測する必要がなく、フィールドの入れ替えミスもなく、呼び出し元のコードが明確です。
ランタイム依存は1つだけ。 JSONシリアライズ用のJackson。その他は標準ライブラリのみ。OkHttp、Apache HttpClient、Guavaは使いません。
Java 11以上。 Java 11で導入されたjava.net.http.HttpClientを使用。プロジェクトがJava 8以前をターゲットにしている場合、SDKは非対応です。
クイックリファレンス
| メソッド | エンドポイント | 認証必要 |
|---|---|---|
client.health() | GET /health | いいえ |
client.languages() | GET /languages | いいえ |
client.translate(...) | POST /translate | はい |
client.batch(...) | POST /translate/batch | はい |
client.usage() | GET /usage | はい |
client.jobs().create(...) | POST /jobs | はい |
client.jobs().get(jobId) | GET /jobs/:id | はい |
client.jobs().translate(...) | POST /jobs + ポーリング | はい |
はじめに
SDKはMaven Centralのcentral.sonatype.com/artifact/com.usepolylingo/polylingoにあります。ソースコードとJavadocはgithub.com/UsePolyLingo/polylingo-Javaにあります。完全なAPIドキュメントはusepolylingo.com/docs/sdk/javaにあります。
無料プランは月50,000トークンを含みます。クレジットカードは不要です。
<dependency>
<groupId>com.usepolylingo</groupId>
<artifactId>polylingo</artifactId>
<version>0.1.0</version>
</dependency>