Google Cloud Translation v3 は、100 を超える言語間でテキストを翻訳し、あるテキストの言語を検出することもできます。このサービスは gRPC 経由で公開されており、sgcWebSockets Enterprise には TsgcGRPCClient の上に構築された型付き Translation gRPC クライアントが付属しています。Protocol Buffers を手作業で組み立てる代わりに、リクエストオブジェクトに値を入れ、1 つのメソッドを呼び出し、型付きレスポンスから直接翻訳済みテキストを読み取ります。この記事では、その仕組みを順を追って説明し、付属のデモにある実際の Delphi コードを示します。
仕組み
gRPC は HTTP/2 上でフレーミングされた Protocol Buffers なので、Translation クライアントは sgcWebSockets の HTTP/2 スタックの上に配置されます。translate.googleapis.com のポート 443 に TLS で向けた TsgcHTTP2Client を作成し、それを TsgcGRPCClient に割り当てると、gRPC コンポーネントがメッセージのフレーミング、ヘッダー、ストリーム処理を代行します。
Translation ユニット sgcGRPC_Google_Translation は、v3 API を反映した型付きメッセージクラスを追加します。翻訳用の TsgcGRPCTranslationTranslateTextRequest と ...TranslateTextResponse、言語検出用の DetectLanguage ペア、言語一覧用の GetSupportedLanguages ペアです。各リクエストは protobuf にシリアライズする ToBytes メソッドを公開し、各レスポンスはレスポンスを解析する LoadFromBytes メソッドを公開します。それらのバイト列を gRPC クライアントの Call メソッドに渡して、結果を読み取ります。
認証
Cloud Translation には Google サービスアカウントのトークンが必要です。デモはサービスアカウントの JSON キー(クライアントメール、秘密鍵 ID、秘密鍵、プロジェクト ID)で認証し、ベアラートークンを取得します。これがその後 gRPC メタデータとして追加され、すべての呼び出しに付随します。
GetGRPCClient.DefaultMetadata.Clear;
GetGRPCClient.DefaultMetadata.Add('authorization', 'Bearer ' + FToken);
注目すべき点が 1 つあります。自己署名のサービスアカウント JWT はオーディエンスにバインドされるため、translate.googleapis.com に受け入れられるには、トークンが Translation エンドポイントを対象にしている必要があります。デモは、トークンを要求する前に JWT.API_Endpoint を https://translate.googleapis.com/ に設定します。
クライアントのセットアップ
HTTP/2 トランスポートと gRPC クライアントは一度だけ組み合わせて接続します。Translation サービスはワイヤ上で protobuf を期待するため、チャネルのコンテンツタイプは grpcProto です。
uses
sgcHTTP2_Client, sgcGRPC_Types, sgcGRPC_Client,
sgcGRPC_Google_Translation;
FHTTP2Client := TsgcHTTP2Client.Create(nil);
FHTTP2Client.Host := 'translate.googleapis.com';
FHTTP2Client.Port := 443;
FHTTP2Client.TLS := True;
FGRPCClient := TsgcGRPCClient.Create(nil);
FGRPCClient.Client := FHTTP2Client;
FGRPCClient.ChannelOptions.ContentType := grpcProto;
FGRPCClient.ChannelOptions.Compression := grpcNoCompression;
テキストの翻訳
翻訳するには、TsgcGRPCTranslationTranslateTextRequest に値を入れます。Parent リソースパスを設定し、Contents に 1 つ以上の文字列を追加し、ソースとターゲットの言語コードおよび MIME タイプを設定します。ToBytes でシリアライズし、完全修飾されたサービス名とメソッドとともに Call に渡します。親パスは v3 形式の projects/<project-id>/locations/global に従います。
var
oRequest: TsgcGRPCTranslationTranslateTextRequest;
oResponse: TsgcGRPCResponse;
begin
oRequest := TsgcGRPCTranslationTranslateTextRequest.Create;
try
oRequest.Parent := 'projects/' + txtProjectId.Text + '/locations/global';
oRequest.Contents.Add(txtSourceText.Text);
oRequest.SourceLanguageCode := txtSourceLang.Text; // e.g. 'en'
oRequest.TargetLanguageCode := txtTargetLang.Text; // e.g. 'es'
oRequest.MimeType := 'text/plain';
oResponse := GetGRPCClient.Call
('google.cloud.translation.v3.TranslationService', 'TranslateText',
oRequest.ToBytes);
finally
oRequest.Free;
end;
end;
レスポンスは TsgcGRPCResponse として返ってきます。StatusCode が grpcOK のとき、生の Data バイト列を型付きレスポンスに読み込み、各翻訳を読み取ります。各 Translation には TranslatedText が含まれ、ソース言語が自動検出された場合は DetectedLanguageCode も含まれます。
var
oResponse: TsgcGRPCTranslationTranslateTextResponse;
i: Integer;
begin
oResponse := TsgcGRPCTranslationTranslateTextResponse.Create;
try
oResponse.LoadFromBytes(aData);
for i := 0 to oResponse.TranslationCount - 1 do
begin
DoLog('Translated: ' + oResponse.Translation(i).TranslatedText);
if oResponse.Translation(i).DetectedLanguageCode <> '' then
DoLog('Detected: ' + oResponse.Translation(i).DetectedLanguageCode);
end;
finally
oResponse.Free;
end;
end;
言語の検出
ソース言語が分からない場合は、翻訳はいったん置いておき、DetectLanguage を呼び出します。親パスと検査する Content を指定して TsgcGRPCTranslationDetectLanguageRequest を構築し、候補となる言語を読み取ります。各候補には LanguageCode と Confidence 値が付きます。
oRequest := TsgcGRPCTranslationDetectLanguageRequest.Create;
try
oRequest.Parent := GetParentPath;
oRequest.Content := txtSourceText.Text;
oRequest.MimeType := 'text/plain';
oResponse := GetGRPCClient.Call
('google.cloud.translation.v3.TranslationService', 'DetectLanguage',
oRequest.ToBytes);
finally
oRequest.Free;
end;
検出レスポンスを解析すると、各候補の言語コードと信頼度スコアが得られます。
oResponse := TsgcGRPCTranslationDetectLanguageResponse.Create;
try
oResponse.LoadFromBytes(aData);
for i := 0 to oResponse.LanguageCount - 1 do
DoLog('Language: ' + oResponse.Language(i).LanguageCode +
' (confidence: ' + FloatToStr(oResponse.Language(i).Confidence) + ')');
finally
oResponse.Free;
end;
サポート言語の一覧取得
3 つ目の操作 GetSupportedLanguages は、サービスがサポートするすべての言語を返します。表示名をどの言語で取得したいかを DisplayLanguageCode に設定すると、各エントリは LanguageCode と人間が読める DisplayName、そしてソースまたはターゲットとして使用できるかどうかのフラグとともに返ってきます。
oRequest := TsgcGRPCTranslationGetSupportedLanguagesRequest.Create;
try
oRequest.Parent := GetParentPath;
oRequest.DisplayLanguageCode := 'en';
oResponse := GetGRPCClient.Call
('google.cloud.translation.v3.TranslationService',
'GetSupportedLanguages', oRequest.ToBytes);
finally
oRequest.Free;
end;
提供状況
Translation gRPC クライアントは sgcWebSockets Enterprise エディションの一部で、Delphi と C++Builder にわたり Windows、macOS、Linux、iOS、Android で動作します。サービスアカウントの読み込みと 3 つすべての操作を備えた、すぐに実行できる完全なサンプルは Demos\21.GRPC\12.Translation にあり、基盤となる gRPC クライアントは gRPC Client 製品ページに記載されています。
ご質問やご意見はありますか? お問い合わせください。コードを書いた本人から返信いたします。
