プログラムから Translator Text API を使用してテキストを翻訳する
事前に用意するもの
事前に Microsoft Azure のアカウントを作成しておいてください。作成手順についてはこちらのページで説明しています。
また、今回は無料版で登録するので、有料版を使いたい場合は適時変更してください。
API のリソースを作成
Microsoft Azure のポータル画面を開き、左のメニューにある「新規」をクリックします。
展開されたメニューから「Intelligence + analytics」を選択します。
さらに展開されたメニューから「Cognitive Services APIs (プレビュー)」を選択します。
作成画面が表示されるので、任意のアカウント名を入力し(ダッシュボードでの表示名になります)、サブスクリプションは「無料試用版」を選択します。次に API type をクリックします。
API の一覧から「Translator Text API」を選択します。
続いて Pricing tier を選択します。
無料版を使うので「F0 Free」をクリックして「選択」ボタンをクリックします。無料版は月200万文字まで変換できます。
初めてサービスを登録する場合は Resource group を新規作成してください。作成したリソースを任意の名前のグループにまとめることができます。
ロケーションはサービスを置く場所です。日本を中心に展開する場合は日本に設置したほうがパフォーマンスが上がる可能性が高いです。
最後に「ダッシュボードにピン留めする」にチェックをいれて「作成」ボタンをクリックします。
ダッシュボードに先ほど作成したリソースがあるのでクリックして開きます。
Overview が開かれていると思いますので、右にある「Endpoint」の URL を確認します。これが最初に認証でアクセスすべき API の URL になります。ただし、めったに変わりませんし、あとで紹介するプログラムにも記載していますので、一応ここにあるということを覚えていればよいです。
メニューから「Keys」を選択します。
表示された「KEY 1」をメモしておきます。このキーを使用して認証を行います。キーが2つあるのはおそらく予備ではないかと思います。ちなみに何らかの原因でキーが外部に漏れてしまった場合は、上にある「Regenerate…」で再作成することができます。
これで Azure 側の設定は終わりになります。
プログラムから API にアクセスしてテキストを翻訳する
次は実際にプログラムを作成してテキストを翻訳できるようにします。Visual Studio 2015 を使用して WPF アプリケーションを作成し、次のような画面を作成します。
「変換元」にテキストを入力し、「言語」にどの言語からどの言語に変換するかを入力します。そして「変換実行」ボタンをクリックすると、下の「変換先」に翻訳されたテキストが表示されるようになります。
XAML (MainWindow.xaml)
翻訳には直接影響しませんので、コードのみ記載します。
<Window x:Class="AzureTranslatorTextApi.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AzureTranslatorTextApi"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label x:Name="label" Content="変換元" HorizontalAlignment="Left" Grid.Row="0"/>
<TextBox x:Name="textBoxInput" Margin="4" Text="ここに変換するテキストを入力します。" Grid.Row="1" AcceptsReturn="True" AcceptsTab="True" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"/>
<Label x:Name="labelLang" Content="言語" HorizontalAlignment="Left" Grid.Row="2"/>
<Label x:Name="labelLangFrom" Content="from" HorizontalAlignment="Left" Grid.Row="2" Margin="56,0,0,0"/>
<TextBox x:Name="textBoxLangFrom" Margin="96,4,0,4" HorizontalAlignment="Left" Text="ja" Grid.Row="2" Width="50"/>
<Label x:Name="labelLangTo" Content="to" HorizontalAlignment="Left" Grid.Row="2" Margin="164,0,0,0"/>
<TextBox x:Name="textBoxLangTo" Margin="190,4,0,4" HorizontalAlignment="Left" Text="en" Grid.Row="2" Width="50" />
<Button x:Name="button" Content="変換実行" Margin="24,4" Height="24" Grid.Row="3" Click="button_Click"/>
<Label x:Name="label_Copy" Content="変換先" HorizontalAlignment="Left" Grid.Row="4"/>
<TextBox x:Name="textBoxOutput" Margin="4" Grid.Row="5" AcceptsReturn="True" AcceptsTab="True" VerticalScrollBarVisibility="Auto" IsReadOnly="True" Background="#FFE8E8E8" HorizontalScrollBarVisibility="Auto"/>
</Grid>
</Window>
アクセストークン取得 (MainWindow.xaml.cs)
テキスト翻訳のための基本的な流れとしては
- KEY 1 を API に投げてアクセストークンを取得する。
- アクセストークンを使用してテキストを翻訳サービスに投げて翻訳したテキストを取得する。
- 必要に応じて再度アクセストークンを取得する
となります。
まずはアクセストークンを取得するメソッドを定義して使いやすくしましょう。引数に先ほど取得した KEY 1 を渡すとアクセストークンを取得できるようになっています。同期処理でも取得できるのですが、C# 5.0 からは async/await が使えるので手軽に非同期処理にしましょう。
ポイントとしては URL に Azure で確認した Endpoint +「/issueToken」を設定するのと、送信する Header に「Ocp-Apim-Subscription-Key」をキーとして取得した KEY 1 を設定します。
レスポンスとしてはアクセストークンの文字列がそのまま取得できるので、それを戻り値としています。ちなみにこのアクセストークンは10分間のみ有効となります。
<summary>
非同期でアクセストークンを取得します。
</summary>
<param name="subscriptionKey">認証に必要なキー文字列。</param>
<returns>取得したアクセストークン。</returns>
private async Task<string> GetAccessTokenAsync(string subscriptionKey)
{
using (var client = new HttpClient())
using (var request = new HttpRequestMessage())
{
request.Method = HttpMethod.Post;
request.RequestUri = new Uri("https://api.cognitive.microsoft.com/sts/v1.0/issueToken");
request.Content = new StringContent(string.Empty);
request.Headers.TryAddWithoutValidation("Ocp-Apim-Subscription-Key", subscriptionKey);
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var token = await response.Content.ReadAsStringAsync();
Trace.WriteLine($"token={token}");
return token;
}
}
}
API にアクセスしてテキスト翻訳 (MainWindow.xaml.cs)
こちらもメソッド化して使いやすくします。引数に取得したアクセストークンと翻訳するテキスト、どの言語からどの言語に変換するかを指定できるようにします。
アクセスする URL はトークンを取得した URL とは異なるので注意してください。翻訳するテキストや言語は URL のクエリ文字列として送信するので、事前に「Uri.EscapeDataString」を使用してエスケープしておきます。
後は GET メソッドで Header の Authorization にスキーマ「Bearer」とパラメータにトークンを設定して送信します。
レスポンスは XML 形式で取得されるので XDocument を使用して中の翻訳後のテキストを取得しています。ただ、XML を使用しているせいか XML のエスケープ文字がテキストに含まれている場合、エスケープされたままになっている場合があります。必要に応じて変換してください。
<summary>
テキストを翻訳します。
</summary>
<param name="token">API のアクセスに必要なトークン。</param>
<param name="text">翻訳するテキスト、</param>
<param name="fromLang">翻訳元の言語。</param>
<param name="toLang">翻訳先の言語。</param>
<returns>翻訳されたテキスト。</returns>
private async Task<string> TranslateText(string token, string text, string fromLang, string toLang)
{
using (var client = new HttpClient())
using (var request = new HttpRequestMessage())
{
// URL につけて送信するのでエンコードする
var escapeText = Uri.EscapeDataString(text);
Trace.WriteLine($"escapeText={escapeText}");
var uriStr = "http://api.microsofttranslator.com/V2/Http.svc/Translate?"
+ $"text={escapeText}&from={fromLang}&to={toLang}";
request.Method = HttpMethod.Get;
request.RequestUri = new Uri(uriStr);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var resultText = await response.Content.ReadAsStringAsync();
// <string>XXXXXX</string> 形式で取得されるので XDocument で操作する
XDocument xdoc = XDocument.Parse(resultText);
Trace.WriteLine($"xdoc={xdoc.ToString()}");
// XML エスケープ対象文字が正しく変換されない場合があるので
// 必要があれば対処すること
return xdoc.Descendants().First().Value;
}
}
}
ボタン実行処理 (MainWindow.xaml.cs)
メソッドを2つ実装したら後はそれぞれ呼び出すだけです。KEY1 を設定して入力された値を各メソッドに指定することによってテキストを翻訳することができます。一応非同期処理なのでボタン処理のメソッドに async をつけてください。
private async void button_Click(object sender, RoutedEventArgs e)
{
// ここに認証キー(KEY1)を入力してください
string subscriptionKey = "XXXXXXXXX";
// アクセストークンを取得します。有効時間は10分程度です。(おそらく)
var token = await GetAccessTokenAsync(subscriptionKey);
// テキストを翻訳し表示します
textBoxOutput.Text = await TranslateText(token, textBoxInput.Text, textBoxLangFrom.Text, textBoxLangTo.Text);
}
翻訳可能な言語の一覧
Micorsoft の以下のページを参考にしてください。クラウドサービスの一つなので随時変更される場合があります。