Google Cloud Translation via gRPC dans Delphi

· Composants

Google Cloud Translation v3 traduit du texte entre plus d'une centaine de langues et peut détecter la langue d'un morceau de texte pour vous. Le service est exposé via gRPC, et sgcWebSockets Enterprise fournit un client gRPC Translation typé bâti sur TsgcGRPCClient. Au lieu d'assembler à la main des Protocol Buffers, vous renseignez un objet de requête, appelez une méthode, et lisez le texte traduit directement depuis une réponse typée. Cet article parcourt son fonctionnement et montre le code Delphi réel de la démo fournie.

Comment ça fonctionne

gRPC, ce sont des Protocol Buffers encadrés sur HTTP/2, donc le client Translation repose sur la pile HTTP/2 de sgcWebSockets. Vous créez un TsgcHTTP2Client pointé vers translate.googleapis.com sur le port 443 avec TLS, l'affectez à un TsgcGRPCClient, et le composant gRPC effectue l'encadrement des messages, les en-têtes et la gestion des flux à votre place.

L'unité Translation sgcGRPC_Google_Translation ajoute les classes de messages typées qui reflètent l'API v3 : TsgcGRPCTranslationTranslateTextRequest et ...TranslateTextResponse pour la traduction, la paire DetectLanguage pour la détection de langue, et la paire GetSupportedLanguages pour lister les langues. Chaque requête expose une méthode ToBytes qui la sérialise en protobuf, et chaque réponse expose une méthode LoadFromBytes qui analyse la réponse. Vous passez ces octets à la méthode Call du client gRPC et lisez le résultat en retour.

Authentification

Cloud Translation requiert un jeton de compte de service Google. La démo s'authentifie avec une clé JSON de compte de service (e-mail client, identifiant de clé privée, clé privée et identifiant de projet) et obtient un jeton Bearer, qui est ensuite ajouté en tant que métadonnées gRPC afin qu'il voyage sur chaque appel.

GetGRPCClient.DefaultMetadata.Clear;
GetGRPCClient.DefaultMetadata.Add('authorization', 'Bearer ' + FToken);

Un détail qui mérite d'être noté : un JWT auto-signé de compte de service est lié à une audience, donc le jeton doit cibler l'endpoint Translation pour être accepté par translate.googleapis.com. La démo définit JWT.API_Endpoint sur https://translate.googleapis.com/ avant de demander le jeton.

Configurer le client

Le transport HTTP/2 et le client gRPC sont câblés ensemble une seule fois. Le service Translation attend du protobuf sur le fil, donc le type de contenu du canal est 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;

Traduire du texte

Pour traduire, renseignez un TsgcGRPCTranslationTranslateTextRequest : définissez le chemin de ressource Parent, ajoutez une ou plusieurs chaînes à Contents, définissez les codes de langue source et cible et le type MIME. Sérialisez-le avec ToBytes et passez-le à Call avec le nom et la méthode du service pleinement qualifiés. Le chemin parent suit la forme 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;

La réponse revient sous la forme d'un TsgcGRPCResponse. Lorsque StatusCode vaut grpcOK, chargez les octets Data bruts dans une réponse typée et lisez chaque traduction. Chaque Translation porte le TranslatedText et, lorsque la langue source a été détectée automatiquement, le 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;

Détecter la langue

Lorsque vous ne connaissez pas la langue source, laissez la traduction de côté et appelez DetectLanguage. Construisez un TsgcGRPCTranslationDetectLanguageRequest avec le chemin parent et le Content à inspecter, puis lisez en retour les langues candidates, chacune avec un LanguageCode et une valeur de 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;

L'analyse de la réponse de détection vous donne le code de langue et un score de confiance pour chaque candidat.

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;

Lister les langues prises en charge

La troisième opération, GetSupportedLanguages, renvoie toutes les langues prises en charge par le service. Définissez DisplayLanguageCode sur la langue dans laquelle vous voulez les noms d'affichage, et chaque entrée revient avec un LanguageCode et un DisplayName lisible, ainsi que des indicateurs précisant si elle peut être utilisée comme source ou cible.

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;

Disponibilité

Le client gRPC Translation fait partie de l'édition Enterprise de sgcWebSockets et fonctionne sous Windows, macOS, Linux, iOS et Android, sur Delphi et C++Builder. Un exemple complet et prêt à l'emploi avec le chargement du compte de service et les trois opérations se trouve dans Demos\21.GRPC\12.Translation, et le client gRPC sous-jacent est documenté sur la page produit du client gRPC.

Des questions ou des commentaires ? Contactez-nous. Vous recevrez une réponse des personnes qui ont écrit le code.