[2021Aug] Azure Cognitive Services を試すための記述量が少なすぎた

# はじめに
Azure Cognitive Services の Text Analytics API を利用した NLP アプリがありまして、どうも期待通りに使えず、何が原因かと探る一環として、自分でも同 API を試してみることにしました。こんな引数で成功して、こんな引数で失敗して、エラーは何で、みたいなことをざっと見渡したいと考えました。

すると。

１画面に収まる記述量で同 API を使えてしまいましたとさ。すごい。

せっかくなのでメモを残します。


# 何を試したか

Text Analytics API の Detect Language を試しました。

同 API は REST API です。[公式ドキュメント](https://westus2.dev.cognitive.microsoft.com/docs/services/TextAnalytics-v3-1/operations/Languages)では HTTP Request / Response について説明されており、サンプルも curl ワンライナーや [System.Net.Http.HttpClient](https://docs.microsoft.com/ja-jp/dotnet/api/system.net.http.httpclient?view=net-5.0) クラスを利用したものが紹介されています。

ここでは C# で [Azure.AI.TextAnalytics.TextAnalyticsClient](https://docs.microsoft.com/en-us/dotnet/api/azure.ai.textanalytics.textanalyticsclient?view=azure-dotnet) クラスを利用しました。


# どのように試したか

環境は Linux 上の .NET 5.0.302 を利用しました。

## 手順概略

1. dotnet コマンドでプロジェクト作成
1. dotnet コマンドでパッケージ追加
1. コード記述
1. dotnet コマンドでプロジェクトをビルド＆実行


## 手順詳細

### プロジェクト作成

コマンドは下記です。

```shell
$ dotnet new console -n experiment -o ./
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on ./experiment.csproj...
  Determining projects to restore...
  Restored /home/developer/app/experiment.csproj (in 57 ms).
Restore succeeded.
```

### パッケージ追加

.NET に標準で含まれないパッケージを利用しますので、プロジェクトにパッケージを追加します。

コマンドは下記です。

```shell
$ dotnet add package -v 5.1.0 Azure.AI.TextAnalytics
  Determining projects to restore...
  Writing /tmp/tmp0evPUW.tmp
info : Adding PackageReference for package 'Azure.AI.TextAnalytics' into project '/home/developer/app/experiment.csproj'.
info : Restoring packages for /home/developer/app/experiment.csproj...
info :   GET https://api.nuget.org/v3-flatcontainer/azure.ai.textanalytics/index.json
info :   OK https://api.nuget.org/v3-flatcontainer/azure.ai.textanalytics/index.json 723ms
info :   GET https://api.nuget.org/v3-flatcontainer/azure.ai.textanalytics/5.1.0/azure.ai.textanalytics.5.1.0.nupkg
info :   OK https://api.nuget.org/v3-flatcontainer/azure.ai.textanalytics/5.1.0/azure.ai.textanalytics.5.1.0.nupkg 43ms
info :   GET https://api.nuget.org/v3-flatcontainer/azure.core/index.json
info :   GET https://api.nuget.org/v3-flatcontainer/microsoft.bcl.asyncinterfaces/index.json
info :   GET https://api.nuget.org/v3-flatcontainer/system.text.json/index.json
info :   OK https://api.nuget.org/v3-flatcontainer/system.text.json/index.json 458ms
info :   GET https://api.nuget.org/v3-flatcontainer/system.text.json/4.6.0/system.text.json.4.6.0.nupkg
info :   OK https://api.nuget.org/v3-flatcontainer/system.text.json/4.6.0/system.text.json.4.6.0.nupkg 62ms
info :   OK https://api.nuget.org/v3-flatcontainer/azure.core/index.json 732ms
info :   GET https://api.nuget.org/v3-flatcontainer/azure.core/1.16.0/azure.core.1.16.0.nupkg
info :   OK https://api.nuget.org/v3-flatcontainer/azure.core/1.16.0/azure.core.1.16.0.nupkg 57ms
info :   OK https://api.nuget.org/v3-flatcontainer/microsoft.bcl.asyncinterfaces/index.json 917ms
info :   GET https://api.nuget.org/v3-flatcontainer/microsoft.bcl.asyncinterfaces/1.0.0/microsoft.bcl.asyncinterfaces.1.0.0.nupkg
info :   GET https://api.nuget.org/v3-flatcontainer/system.buffers/index.json
info :   GET https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/index.json
info :   GET https://api.nuget.org/v3-flatcontainer/system.memory/index.json
info :   GET https://api.nuget.org/v3-flatcontainer/system.memory.data/index.json
info :   GET https://api.nuget.org/v3-flatcontainer/system.numerics.vectors/index.json
info :   GET https://api.nuget.org/v3-flatcontainer/system.text.encodings.web/index.json
info :   GET https://api.nuget.org/v3-flatcontainer/system.threading.tasks.extensions/index.json
info :   OK https://api.nuget.org/v3-flatcontainer/microsoft.bcl.asyncinterfaces/1.0.0/microsoft.bcl.asyncinterfaces.1.0.0.nupkg 61ms
info :   OK https://api.nuget.org/v3-flatcontainer/system.threading.tasks.extensions/index.json 448ms
info :   GET https://api.nuget.org/v3-flatcontainer/system.threading.tasks.extensions/4.5.2/system.threading.tasks.extensions.4.5.2.nupkg
info :   OK https://api.nuget.org/v3-flatcontainer/system.threading.tasks.extensions/4.5.2/system.threading.tasks.extensions.4.5.2.nupkg 54ms
info :   OK https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/index.json 762ms
info :   OK https://api.nuget.org/v3-flatcontainer/system.buffers/index.json 764ms
info :   GET https://api.nuget.org/v3-flatcontainer/system.buffers/4.5.1/system.buffers.4.5.1.nupkg
info :   GET https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/4.6.0/system.diagnostics.diagnosticsource.4.6.0.nupkg
info :   OK https://api.nuget.org/v3-flatcontainer/system.buffers/4.5.1/system.buffers.4.5.1.nupkg 42ms
info :   OK https://api.nuget.org/v3-flatcontainer/system.diagnostics.diagnosticsource/4.6.0/system.diagnostics.diagnosticsource.4.6.0.nupkg 78ms
info :   OK https://api.nuget.org/v3-flatcontainer/system.memory.data/index.json 873ms
info :   GET https://api.nuget.org/v3-flatcontainer/system.memory.data/1.0.2/system.memory.data.1.0.2.nupkg
info :   OK https://api.nuget.org/v3-flatcontainer/system.memory/index.json 879ms
info :   GET https://api.nuget.org/v3-flatcontainer/system.memory/4.5.4/system.memory.4.5.4.nupkg
info :   OK https://api.nuget.org/v3-flatcontainer/system.numerics.vectors/index.json 908ms
info :   GET https://api.nuget.org/v3-flatcontainer/system.numerics.vectors/4.5.0/system.numerics.vectors.4.5.0.nupkg
info :   OK https://api.nuget.org/v3-flatcontainer/system.memory.data/1.0.2/system.memory.data.1.0.2.nupkg 51ms
info :   OK https://api.nuget.org/v3-flatcontainer/system.text.encodings.web/index.json 933ms
info :   OK https://api.nuget.org/v3-flatcontainer/system.memory/4.5.4/system.memory.4.5.4.nupkg 57ms
info :   GET https://api.nuget.org/v3-flatcontainer/system.text.encodings.web/4.7.2/system.text.encodings.web.4.7.2.nupkg
info :   OK https://api.nuget.org/v3-flatcontainer/system.numerics.vectors/4.5.0/system.numerics.vectors.4.5.0.nupkg 59ms
info :   OK https://api.nuget.org/v3-flatcontainer/system.text.encodings.web/4.7.2/system.text.encodings.web.4.7.2.nupkg 70ms
info : Installed System.Memory.Data 1.0.2 from https://api.nuget.org/v3/index.json with content hash JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==.
info : Installed System.Threading.Tasks.Extensions 4.5.2 from https://api.nuget.org/v3/index.json with content hash BG/TNxDFv0svAzx8OiMXDlsHfGw623BZ8tCXw4YLhDFDvDhNUEV58jKYMGRnkbJNm7c3JNNJDiN7JBMzxRBR2w==.
info : Installed System.Memory 4.5.4 from https://api.nuget.org/v3/index.json with content hash 1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==.
info : Installed System.Text.Encodings.Web 4.7.2 from https://api.nuget.org/v3/index.json with content hash iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==.
info : Installed Azure.AI.TextAnalytics 5.1.0 from https://api.nuget.org/v3/index.json with content hash dLTJ09BpZjcMQFHsYx916HiaQw/ZA2cKXmxGSMpW06GYYQ9QccsTVXXqqiGWnUqRPBaRqBQGSazcXEeatkDFQQ==.
info : Installed System.Diagnostics.DiagnosticSource 4.6.0 from https://api.nuget.org/v3/index.json with content hash mbBgoR0rRfl2uimsZ2avZY8g7Xnh1Mza0rJZLPcxqiMWlkGukjmRkuMJ/er+AhQuiRIh80CR/Hpeztr80seV5g==.
info : Installed System.Buffers 4.5.1 from https://api.nuget.org/v3/index.json with content hash Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==.
info : Installed System.Text.Json 4.6.0 from https://api.nuget.org/v3/index.json with content hash 4F8Xe+JIkVoDJ8hDAZ7HqLkjctN/6WItJIzQaifBwClC7wmoLSda/Sv2i6i1kycqDb3hWF4JCVbpAweyOKHEUA==.
info : Installed Microsoft.Bcl.AsyncInterfaces 1.0.0 from https://api.nuget.org/v3/index.json with content hash K63Y4hORbBcKLWH5wnKgzyn7TOfYzevIEwIedQHBIkmkEBA9SCqgvom+XTuE+fAFGvINGkhFItaZ2dvMGdT5iw==.
info : Installed Azure.Core 1.16.0 from https://api.nuget.org/v3/index.json with content hash DT/d7TTwBiyU/Me0MISk7qFDGeFUBlZoLXJKWrXN86oSRieaeeYZ+LKN4dINkWQ0VMEqv6FlhY4AbAdPiGan6w==.
info : Installed System.Numerics.Vectors 4.5.0 from https://api.nuget.org/v3/index.json with content hash QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==.
info : Package 'Azure.AI.TextAnalytics' is compatible with all the specified frameworks in project '/home/developer/app/experiment.csproj'.
info : PackageReference for package 'Azure.AI.TextAnalytics' version '5.1.0' added to file '/home/developer/app/experiment.csproj'.
info : Committing restore...
info : Generating MSBuild file /home/developer/app/obj/experiment.csproj.nuget.g.props.
info : Generating MSBuild file /home/developer/app/obj/experiment.csproj.nuget.g.targets.
info : Writing assets file to disk. Path: /home/developer/app/obj/project.assets.json
log  : Restored /home/developer/app/experiment.csproj (in 4 sec).
```

パッケージを追加した結果のプロジェクト・ファイルは下記です。

```experiment.csproj 
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Azure.AI.TextAnalytics" Version="5.1.0" />
  </ItemGroup>

</Project>
```


### コード記述

書いたコードは下記です。文字コードは UTF-8 です。
`MICROSOFT_TEXT_ANALYTICS_ENDPOINT` と `MICROSOFT_TEXT_ANALYTICS_KEY` はプレースホルダです。

```Program.cs 
using Azure;
using Azure.AI.TextAnalytics;
using System;

namespace experiment
{
  class Program
  {
    static void Main(string[] args)
    {
      TextAnalyticsClient        ta_client;
      Response<DetectedLanguage> res_t;
      Response                   res;
      DetectedLanguage           dl;

      ta_client = new TextAnalyticsClient(
        new Uri(MICROSOFT_TEXT_ANALYTICS_ENDPOINT),
        new AzureKeyCredential(MICROSOFT_TEXT_ANALYTICS_KEY)
      );

      res_t = ta_client.DetectLanguage("これはペンです。");
      res   = res_t.GetRawResponse();
      dl    = res_t.Value;

      Console.WriteLine("HTTP Response =>\n" + res.ToString());
      Console.WriteLine("Score : " + dl.ConfidenceScore);
      Console.WriteLine("Short Name : " + dl.Iso6391Name);
      Console.WriteLine("Name : " + dl.Name);
    }
  }
}
```


### プロジェクトをビルド＆実行

コマンドは下記です。
無事に `Japanese` と判別されました。

```shell
$ dotnet run
HTTP Response =>
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: <null>, Headers:
{
  Transfer-Encoding: chunked
  csp-billing-usage: CognitiveServices.TextAnalytics.BatchScoring=1,CognitiveServices.TextAnalytics.TextRecords=1
  x-envoy-upstream-service-time: 12
  apim-request-id: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
  Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  X-Content-Type-Options: nosniff
  Date: Sat, 07 Aug 2021 07:38:13 GMT
}
Score : 1
Short Name : ja
Name : Japanese
```


# おわりに

冒頭で「１画面に収まる記述量」と書きましたが、２つのファイル `experiment.csproj` と `Program.cs` のファイルサイズの合計は、1174バイトでした。

お手軽です。