.NET 用 Azure Cognitive Services ドキュメント翻訳クライアント ライブラリ - バージョン 1.0.0

Azure Cognitive Services Document Translation は、ドキュメントの構造とデータ形式を維持しながら、90 の言語と方言との間でドキュメントを翻訳するクラウド サービスです。 ドキュメント翻訳用のクライアント ライブラリを使用して、次の手順を実行します。

  • 多数の大きなファイルを、Azure Blob Storage コンテナーから任意の言語のターゲット コンテナーに変換します。
  • 翻訳操作で各ドキュメントの翻訳状態と進行状況を確認します。
  • カスタム翻訳モデルまたは用語集を適用して、特定のケースに合わせて翻訳を調整します。

ソースコード | パッケージ (NuGet) | API リファレンス ドキュメント | 製品ドキュメント | サンプル

作業の開始

パッケージをインストールする

NuGet を使用して .NET 用の Azure Document Translation クライアント ライブラリをインストールします。

dotnet add package Azure.AI.Translation.Document

注: このバージョンのクライアント ライブラリは、既定でサービスの v1.0 バージョンになります。

前提条件

Translator リソースを作成する

ドキュメント翻訳では、 単一サービス アクセス のみがサポートされます。 サービスにアクセスするには、Translator リソースを作成します。

次を使用して、いずれかのリソースを作成できます。

オプション 1:Azure Portal

オプション 2:Azure CLI

CLI を使用して Translator リソースを作成する方法の例を次に示します。

# Create a new resource group to hold the Translator resource -
# if using an existing resource group, skip this step
az group create --name <your-resource-name> --location <location>
# Create Translator
az cognitiveservices account create \
    --name <your-resource-name> \
    --custom-domain <your-resource-name> \
    --resource-group <your-resource-group-name> \
    --kind TextTranslation \
    --sku S1 \
    --location <location> \
    --yes

リソースの作成または場所情報の取得方法の詳細については、 こちらを参照してください

クライアントを認証する

Document Translation サービスを操作するには、 DocumentTranslationClient クラスのインスタンスを作成する必要があります。 エンドポイントAPI キー、または TokenCredential クライアント オブジェクトをインスタンス化する必要があります。 コグニティブ サービスを使用した認証の詳細については、「 Azure Cognitive Services への要求を認証する」を参照してください。

エンドポイントの参照

ドキュメント翻訳の場合は、Translator リソースの名前を使用してCustom Domain エンドポイントを使用する必要があります。

API キーを取得する

は、Azure Portal の Translator リソース情報から取得API keyできます。

または、以下の Azure CLI スニペットを使用して、Translator リソースから API キーを取得します。

az cognitiveservices account keys list --resource-group <your-resource-group-name> --name <your-resource-name>

API キー資格情報を使用して DocumentTranslationClient を作成する

API キーの値を取得したら、 を作成します AzureKeyCredential。 これにより、新しいクライアントを作成せずに API キーを更新できます。

エンドポイントと の値を AzureKeyCredential使用すると、 DocumentTranslationClient を作成できます。

string endpoint = "<Document Translator Resource Endpoint>";
string apiKey = "<Document Translator Resource API Key>";
var client = new DocumentTranslationClient(new Uri(endpoint), new AzureKeyCredential(apiKey));

Azure Active Directory 資格情報を使用して DocumentTranslationClient を作成する

クライアント API キー認証は、このファースト ステップ ガイドのほとんどの例で使用されますが、Azure Id ライブラリを使用して Azure Active Directory で認証することもできます。 リージョン エンドポイントは AAD 認証をサポートしないことに注意してください。

この種類の認証を使用するために、リソースのカスタム サブドメインを作成します。

以下に示す DefaultAzureCredential プロバイダー、または Azure SDK で提供されているその他の資格情報プロバイダーを使用するには、Azure.Identity パッケージをインストールしてください。

dotnet add package Azure.Identity

また、新しい AAD アプリケーションを登録し、サービス プリンシパルにロールを割り当てること"Cognitive Services User"で Translator リソースへのアクセス権を付与する必要があります。

AAD アプリケーションの client ID、、および client secret の値を環境変数として設定します。 AZURE_CLIENT_IDAZURE_TENANT_IDAZURE_CLIENT_SECRETtenant ID

string endpoint = "<Document Translator Resource Endpoint>";
var client = new DocumentTranslationClient(new Uri(endpoint), new DefaultAzureCredential());

主要な概念

ドキュメント翻訳サービスでは、ファイルをAzure Blob Storageソース コンテナーにアップロードし、翻訳されたドキュメントを書き込むことができるターゲット コンテナーを指定する必要があります。 コンテナー (またはファイル) への SAS トークンは、ドキュメントにアクセスし、ターゲット コンテナーに翻訳されたドキュメントを作成するために使用されます。 この設定に関する追加情報については、サービスのドキュメントを参照してください。

DocumentTranslationClient

DocumentTranslationClientは、Document Translation クライアント ライブラリを使用する開発者向けの主要なインターフェイスです。 次の操作を実行するための同期メソッドと非同期メソッドの両方が提供されます。

  • 変換操作を作成して、ソース コンテナー内のドキュメントを翻訳し、ターゲット コンテナーに結果を書き込みます。
  • 過去と現在のすべての翻訳操作を列挙します。
  • サポートされている用語集とドキュメントの形式を特定する。

翻訳入力

翻訳操作を開始するには、1 つのインスタンスまたは の DocumentTranslationInputリストを作成する必要があります。

ドキュメントへの 1 つのソース URL は、さまざまな言語に翻訳できます。

Uri sourceSasUri = new Uri("<source SAS URI>");
Uri frenchTargetSasUri = new Uri("<french target SAS URI>");
var input = new DocumentTranslationInput(sourceSasUri, frenchTargetSasUri, "fr");

または、複数の異なるソースにそれぞれ独自のターゲットを指定できます。

Uri arabicTargetSasUri = new Uri("<arabic target SAS URI>");
Uri spanishTargetSasUri = new Uri("<spanish target SAS URI>");
Uri source1SasUri = new Uri("<source1 SAS URI>");
Uri source2SasUri = new Uri("<source2 SAS URI>");

var inputs = new List<DocumentTranslationInput>
{
    new DocumentTranslationInput(source1SasUri, spanishTargetSasUri, "es"),
    new DocumentTranslationInput(
        source: new TranslationSource(source2SasUri),
        targets: new List<TranslationTarget>
        {
            new TranslationTarget(frenchTargetSasUri, "fr"),
            new TranslationTarget(arabicTargetSasUri, "ar")
        }),
};

ターゲット コンテナーに書き込まれるドキュメントには、一意の名前が必要であることに注意してください。 そのため、ソース コンテナーをターゲット コンテナーに 2 回変換したり、同じドキュメントを含むソースを同じターゲット コンテナーに変換したりすることはできません。

Long-Running操作

ドキュメント翻訳は、 実行時間の長い操作として実装されます。 実行時間の長い操作は、操作を開始するためにサービスに送信された最初の要求で構成され、その後、操作が正常に完了したか失敗したかを判断する間隔でサービスをポーリングします。

Azure SDK で実行時間の長い操作を行う場合、クライアントは を Start<operation-name> 返すメソッドを PageableOperation<T>公開します。 拡張メソッド WaitForCompletionAsync() を使用すると、操作が完了するまで待機し、その結果を取得できます。 以下に、実行時間の長い操作を使用する方法を示すサンプル コード スニペットを示 します

スレッド セーフ

すべてのクライアント インスタンス メソッドがスレッド セーフであり、相互に独立していることを保証します (ガイドライン)。 これにより、スレッド間であっても、クライアント インスタンスの再利用に関する推奨事項が常に安全になります。

その他の概念

クライアント オプション | 応答 | へのアクセスエラーの | 処理診断 | あざける | クライアントの有効期間

次のセクションでは、上記で作成したclient使用したいくつかのコード スニペットと、ドキュメント翻訳のメイン関数について説明します。 注: 同期 DocumentTranslationClient メソッドと非同期メソッドの両方が用意されています。

非同期の例

同期の例

注: 同期 DocumentTranslationClient メソッドと非同期メソッドの両方が用意されています。

翻訳を非同期的に開始する

変換操作を開始して、ソース コンテナー内のドキュメントを翻訳し、翻訳されたファイルをターゲット コンテナーに書き込みます。 DocumentTranslationOperation では、翻訳操作の状態をポーリングし、個々のドキュメントの状態を取得できます。

Uri sourceUri = new Uri("<source SAS URI>");
Uri targetUri = new Uri("<target SAS URI>");
var input = new DocumentTranslationInput(sourceUri, targetUri, "es");

DocumentTranslationOperation operation = await client.StartTranslationAsync(input);

await operation.WaitForCompletionAsync();

Console.WriteLine($"  Status: {operation.Status}");
Console.WriteLine($"  Created on: {operation.CreatedOn}");
Console.WriteLine($"  Last modified: {operation.LastModified}");
Console.WriteLine($"  Total documents: {operation.DocumentsTotal}");
Console.WriteLine($"    Succeeded: {operation.DocumentsSucceeded}");
Console.WriteLine($"    Failed: {operation.DocumentsFailed}");
Console.WriteLine($"    In Progress: {operation.DocumentsInProgress}");
Console.WriteLine($"    Not started: {operation.DocumentsNotStarted}");

await foreach (DocumentStatusResult document in operation.Value)
{
    Console.WriteLine($"Document with Id: {document.Id}");
    Console.WriteLine($"  Status:{document.Status}");
    if (document.Status == DocumentTranslationStatus.Succeeded)
    {
        Console.WriteLine($"  Translated Document Uri: {document.TranslatedDocumentUri}");
        Console.WriteLine($"  Translated to language code: {document.TranslatedToLanguageCode}.");
        Console.WriteLine($"  Document source Uri: {document.SourceDocumentUri}");
    }
    else
    {
        Console.WriteLine($"  Error Code: {document.Error.Code}");
        Console.WriteLine($"  Message: {document.Error.Message}");
    }
}

操作履歴を非同期的に取得する

過去 7 日間に送信された翻訳操作の履歴を取得します。 ユーザーが送信されたすべての操作を返す場合は、options パラメーターを指定できます。

int operationsCount = 0;
int totalDocs = 0;
int docsCanceled = 0;
int docsSucceeded = 0;
int docsFailed = 0;

DateTimeOffset lastWeekTimestamp = DateTimeOffset.Now.AddDays(-7);

var options = new GetTranslationStatusesOptions
{
    CreatedAfter = lastWeekTimestamp
};

await foreach (TranslationStatusResult translationStatus in client.GetTranslationStatusesAsync(options))
{
    if (translationStatus.Status == DocumentTranslationStatus.NotStarted ||
        translationStatus.Status == DocumentTranslationStatus.Running)
    {
        DocumentTranslationOperation operation = new DocumentTranslationOperation(translationStatus.Id, client);
        await operation.WaitForCompletionAsync();
    }

    operationsCount++;
    totalDocs += translationStatus.DocumentsTotal;
    docsCanceled += translationStatus.DocumentsCanceled;
    docsSucceeded += translationStatus.DocumentsSucceeded;
    docsFailed += translationStatus.DocumentsFailed;
}

Console.WriteLine($"# of operations: {operationsCount}");
Console.WriteLine($"Total Documents: {totalDocs}");
Console.WriteLine($"Succeeded Document: {docsSucceeded}");
Console.WriteLine($"Failed Document: {docsFailed}");
Console.WriteLine($"Canceled Documents: {docsCanceled}");

複数の入力を使用して非同期的に翻訳を開始する

翻訳操作を開始して、複数のソース コンテナー内のドキュメントを異なる言語の複数のターゲット コンテナーに翻訳します。 DocumentTranslationOperation では、翻訳操作の状態をポーリングし、個々のドキュメントの状態を取得できます。

Uri source1SasUri = new Uri("<source1 SAS URI>");
Uri source2SasUri = new Uri("<source2 SAS URI>");
Uri frenchTargetSasUri = new Uri("<french target SAS URI>");
Uri arabicTargetSasUri = new Uri("<arabic target SAS URI>");
Uri spanishTargetSasUri = new Uri("<spanish target SAS URI>");
Uri frenchGlossarySasUri = new Uri("<french glossary SAS URI>");

var glossaryFormat = "TSV";

var input1 = new DocumentTranslationInput(source1SasUri, frenchTargetSasUri, "fr", new TranslationGlossary(frenchGlossarySasUri, glossaryFormat));
input1.AddTarget(spanishTargetSasUri, "es");

var input2 = new DocumentTranslationInput(source2SasUri, arabicTargetSasUri, "ar");
input2.AddTarget(frenchTargetSasUri, "fr", new TranslationGlossary(frenchGlossarySasUri, glossaryFormat));

var inputs = new List<DocumentTranslationInput>()
    {
        input1,
        input2
    };

DocumentTranslationOperation operation = await client.StartTranslationAsync(inputs);

await operation.WaitForCompletionAsync();

await foreach (DocumentStatusResult document in operation.GetValuesAsync())
{
    Console.WriteLine($"Document with Id: {document.Id}");
    Console.WriteLine($"  Status:{document.Status}");
    if (document.Status == DocumentTranslationStatus.Succeeded)
    {
        Console.WriteLine($"  Translated Document Uri: {document.TranslatedDocumentUri}");
        Console.WriteLine($"  Translated to language code: {document.TranslatedToLanguageCode}.");
        Console.WriteLine($"  Document source Uri: {document.SourceDocumentUri}");
    }
    else
    {
        Console.WriteLine($"  Document source Uri: {document.SourceDocumentUri}");
        Console.WriteLine($"  Error Code: {document.Error.Code}");
        Console.WriteLine($"  Message: {document.Error.Message}");
    }
}

翻訳の開始

変換操作を開始して、ソース コンテナー内のドキュメントを翻訳し、翻訳されたファイルをターゲット コンテナーに書き込みます。 DocumentTranslationOperation では、翻訳操作の状態をポーリングし、個々のドキュメントの状態を取得できます。

Uri sourceUri = new Uri("<source SAS URI>");
Uri targetUri = new Uri("<target SAS URI>");
var input = new DocumentTranslationInput(sourceUri, targetUri, "es");

DocumentTranslationOperation operation = client.StartTranslation(input);

TimeSpan pollingInterval = new(1000);

while (true)
{
    operation.UpdateStatus();

    Console.WriteLine($"  Status: {operation.Status}");
    Console.WriteLine($"  Created on: {operation.CreatedOn}");
    Console.WriteLine($"  Last modified: {operation.LastModified}");
    Console.WriteLine($"  Total documents: {operation.DocumentsTotal}");
    Console.WriteLine($"    Succeeded: {operation.DocumentsSucceeded}");
    Console.WriteLine($"    Failed: {operation.DocumentsFailed}");
    Console.WriteLine($"    In Progress: {operation.DocumentsInProgress}");
    Console.WriteLine($"    Not started: {operation.DocumentsNotStarted}");

    if (operation.HasCompleted)
    {
        break;
    }
    else
    {
        if (operation.GetRawResponse().Headers.TryGetValue("Retry-After", out string value))
        {
            pollingInterval = TimeSpan.FromSeconds(Convert.ToInt32(value));
        }
        Thread.Sleep(pollingInterval);
    }
}

foreach (DocumentStatusResult document in operation.GetValues())
{
    Console.WriteLine($"Document with Id: {document.Id}");
    Console.WriteLine($"  Status:{document.Status}");
    if (document.Status == DocumentTranslationStatus.Succeeded)
    {
        Console.WriteLine($"  Translated Document Uri: {document.TranslatedDocumentUri}");
        Console.WriteLine($"  Translated to language code: {document.TranslatedToLanguageCode}.");
        Console.WriteLine($"  Document source Uri: {document.SourceDocumentUri}");
    }
    else
    {
        Console.WriteLine($"  Document source Uri: {document.SourceDocumentUri}");
        Console.WriteLine($"  Error Code: {document.Error.Code}");
        Console.WriteLine($"  Message: {document.Error.Message}");
    }
}

トラブルシューティング

全般

.NET SDK を使用して Cognitive Services ドキュメント翻訳クライアント ライブラリを操作する場合、サービスによって返されるエラーは、 REST API 要求に対して返されるのと同じ HTTP 状態コードに対応します。

たとえば、空のターゲット リストを含む要求を送信すると、 400 "Bad Request" を示すエラーが返されます。

var invalidInput = new DocumentTranslationInput(new TranslationSource(new Uri(endpoint)), new List<TranslationTarget>());

try
{
    DocumentTranslationOperation operation = client.StartTranslation(invalidInput);
}
catch (RequestFailedException e)
{
    Console.WriteLine(e.ToString());
}

操作のクライアント要求 ID など、追加情報がログに記録されていることがわかります。

Message:
    Azure.RequestFailedException: Service request failed.
    Status: 400 (Bad Request)

Content:
    {"error":{"code":"InvalidRequest","message":"No translation target found.","target":"TargetInput","innerError":{"code":"NoTranslationTargetFound","message":"No translation target found."}}}

Headers:
    Transfer-Encoding: chunked
    X-RequestId: REDACTED
    Content-Type: application/json; charset=utf-8
    Set-Cookie: REDACTED
    X-Powered-By: REDACTED
    apim-request-id: REDACTED
    Strict-Transport-Security: REDACTED
    x-content-type-options: REDACTED
    Date: Mon, 22 Mar 2021 11:54:58 GMT

コンソール ログの設定

ログを表示する最も簡単な方法は、コンソールログを有効にすることです。 コンソールにメッセージを出力する Azure SDK ログ リスナーを作成するには、AzureEventSourceListener.CreateConsoleLogger メソッドを使用します。

// Setup a listener to monitor logged events.
using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

その他のログメカニズムの詳細については、 こちらを参照してください

次のステップ

Cognitive Services ドキュメント翻訳ライブラリの使用方法を示すサンプルは、この GitHub リポジトリで入手できます。

高度なサンプル

共同作成

このライブラリのビルド、テスト、および投稿の詳細については、 CONTRIBUTING.md を参照してください。

このプロジェクトでは、共同作成と提案を歓迎しています。 ほとんどの共同作成では、共同作成者使用許諾契約書 (CLA) にご同意いただき、ご自身の共同作成内容を使用する権利を Microsoft に供与する権利をお持ちであり、かつ実際に供与することを宣言していただく必要があります。 詳細については、「 cla.microsoft.com」を参照してください。

pull request を送信すると、CLA を提供して PR (ラベル、コメントなど) を適宜装飾する必要があるかどうかを CLA ボットが自動的に決定します。 ボットによって提供される手順にそのまま従ってください。 この操作は、Microsoft の CLA を使用するすべてのリポジトリについて、1 回だけ行う必要があります。

このプロジェクトでは、Microsoft オープン ソースの倫理規定を採用しています。 詳しくは、「Code of Conduct FAQ (倫理規定についてよくある質問)」を参照するか、opencode@microsoft.com 宛てに質問またはコメントをお送りください。

インプレッション数