Download AzureTranslationDemoV3.zip, last updated 11/04/2019 (45.48 KB)

Download
  • md5: 71243a5a58a5b2055e7ffbc8a12dbbbb
  • sha1: b3ea3e69c98e9179121e56912434d6ffa37ed7e9
  • sha256: 5a4c764a08816a7bfc3060ba0006883bf49134838680b88901018ef707a23650
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security;
using System.Text;
using PetaJson;

// Migrating from Azure translation API version 2 to 3
// http://www.cyotek.com/blog/migrating-from-azure-translation-api-version-2-to-3

// Translating text with Azure cognitive services
// http://www.cyotek.com/blog/translating-text-with-azure-cognitive-services

// This work is licensed under the Creative Commons Attribution 4.0 International License.
// To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.

// Found this example useful? 
// https://www.paypal.me/cyotek

namespace Cyotek.Demo.AzureTranslation
{
  public sealed partial class TranslationClient
  {
    #region Constants

    private const string _apiBaseUri = "https://api.cognitive.microsofttranslator.com/";

    private const string _apiVersion = "3.0";

    private const string _apiVersionQueryName = "api-version";

    private const string _getLanguageNamesUri = _apiBaseUri + "languages";

    private const string _getLanguagesForTranslateQuery = "scope=translation";

    private const string _getLanguagesForTranslateUri = _apiBaseUri + "languages";

    private const string _issueTokenUri = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";

    private const int _minutesUntilTokenExpires = 8;

    private const string _queryPrefix = "?" + _apiVersionQueryName + "=" + _apiVersion;

    private const string _translateUri = _apiBaseUri + "translate";

    #endregion

    #region Fields

    private string _authorizationKey;

    private string _authorizationToken;

    private DateTime _timestampWhenTokenExpires;

    #endregion

    #region Constructors

    public TranslationClient()
    {
      _timestampWhenTokenExpires = DateTime.MinValue;
    }

    public TranslationClient(string authorizationKey)
      : this()
    {
      _authorizationKey = authorizationKey;
    }

    #endregion

    #region Properties

    public string AuthorizationKey
    {
      get { return _authorizationKey; }
      set
      {
        if (!string.Equals(_authorizationKey, value))
        {
          _authorizationKey = value;
          _timestampWhenTokenExpires = DateTime.MinValue;
        }
      }
    }

    #endregion

    #region Methods

    public string[] GetLanguages()
    {
      string[] results;

      // https://docs.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-languages?tabs=curl

      results = null;

      this.CheckToken();

      this.ExecuteRequest(_getLanguagesForTranslateUri, _getLanguagesForTranslateQuery, null, response =>
                                                                                              {
                                                                                                Dictionary<string, Dictionary<string, Dictionary<string, string>>> jsonEntities;
                                                                                                Dictionary<string, Dictionary<string, string>> languages;

                                                                                                jsonEntities = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();

                                                                                                using (Stream stream = response.GetResponseStream())
                                                                                                {
                                                                                                  using (StreamReader reader = new StreamReader(stream, this.GetResponseEncoding(response)))
                                                                                                  {
                                                                                                    Json.ParseInto(reader, jsonEntities);
                                                                                                  }
                                                                                                }

                                                                                                results = jsonEntities.TryGetValue("translation", out languages) ? languages.Keys.ToArray() : new string[0];
                                                                                              });

      return results;
    }

    public string GetLocalizedLanguageName(string locale, string language)
    {
      return this.GetLocalizedLanguageNames(locale, new[] { language })[0];
    }

    public string[] GetLocalizedLanguageNames(string locale, string[] languages)
    {
      string[] results;

      // https://docs.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-languages?tabs=curl

      results = null;

      this.CheckToken();

      this.ExecuteRequest(_getLanguageNamesUri, _getLanguagesForTranslateQuery, request => { request.Headers.Add(HttpRequestHeader.AcceptLanguage, locale); }, response =>
                                                                                                                                                               {
                                                                                                                                                                 Dictionary<string, Dictionary<string, Dictionary<string, string>>> jsonEntities;
                                                                                                                                                                 Dictionary<string, Dictionary<string, string>> responseLanguages;

                                                                                                                                                                 jsonEntities = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();

                                                                                                                                                                 using (Stream stream = response.GetResponseStream())
                                                                                                                                                                 {
                                                                                                                                                                   using (StreamReader reader = new StreamReader(stream, this.GetResponseEncoding(response)))
                                                                                                                                                                   {
                                                                                                                                                                     Json.ParseInto(reader, jsonEntities);
                                                                                                                                                                   }
                                                                                                                                                                 }

                                                                                                                                                                 if (jsonEntities.TryGetValue("translation", out responseLanguages))
                                                                                                                                                                 {
                                                                                                                                                                   results = new string [languages.Length];

                                                                                                                                                                   for (int i = 0; i < languages.Length; i++)
                                                                                                                                                                   {
                                                                                                                                                                     Dictionary<string, string> languageData;

                                                                                                                                                                     if (responseLanguages.TryGetValue(languages[i], out languageData))
                                                                                                                                                                     {
                                                                                                                                                                       results[i] = languageData["name"];
                                                                                                                                                                     }
                                                                                                                                                                   }
                                                                                                                                                                 }
                                                                                                                                                                 else
                                                                                                                                                                 {
                                                                                                                                                                   results = new string [0];
                                                                                                                                                                 }
                                                                                                                                                               });

      return results;
    }

    public string Translate(string text, string from, string to)
    {
      string result;
      string queryString;

      // https://docs.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-translate?tabs=curl

      result = null;

      this.CheckToken();

      queryString = "from=" + from + "&to=" + to;

      this.ExecuteRequest(_translateUri, queryString, request =>
                                                      {
                                                        request.ContentType = "application/json";
                                                        request.Method = WebRequestMethods.Http.Post;

                                                        using (Stream stream = request.GetRequestStream())
                                                        {
                                                          using (TextWriter writer = new StreamWriter(stream, Encoding.UTF8))
                                                          {
                                                            Json.Write(writer, new[] { new TextInput(text) }, JsonOptions.DontWriteWhitespace | JsonOptions.Flush | JsonOptions.StrictParser);
                                                          }
                                                        }
                                                      }, response =>
                                                         {
                                                           TranslateResponse[] responses;

                                                           using (Stream stream = response.GetResponseStream())
                                                           {
                                                             using (StreamReader reader = new StreamReader(stream, this.GetResponseEncoding(response)))
                                                             {
                                                               responses = Json.Parse<TranslateResponse[]>(reader);
                                                             }
                                                           }

                                                           result = null;

                                                           if (responses != null && responses.Length == 1)
                                                           {
                                                             TranslateResponse translation;

                                                             translation = responses[0];

                                                             if (translation.Translations != null && translation.Translations.Length == 1)
                                                             {
                                                               result = translation.Translations[0].Text;
                                                             }
                                                           }
                                                         });

      return result;
    }

    private void CheckToken()
    {
      if (DateTime.UtcNow > _timestampWhenTokenExpires)
      {
        this.RefreshToken();
      }
    }

    private HttpWebRequest CreateRequest(string uri, string query)
    {
      HttpWebRequest request;

      if (!string.IsNullOrEmpty(query))
      {
        uri += _queryPrefix + "&" + query;
      }
      else
      {
        uri += _queryPrefix;
      }

      request = WebRequest.CreateHttp(uri);

      if (!string.IsNullOrEmpty(_authorizationToken))
      {
        request.Headers.Add("Authorization", "Bearer " + _authorizationToken);
      }

      request.Accept = "application/json";

      return request;
    }

    private void ExecuteRequest(string uri, string query, Action<HttpWebRequest> init, Action<HttpWebResponse> action)
    {
      HttpWebRequest request;

      request = this.CreateRequest(uri, query);

      try
      {
        init?.Invoke(request);

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
          if (response.StatusCode == HttpStatusCode.OK)
          {
            action(response);
          }
          else
          {
            throw new InvalidOperationException("Unexpected response code.");
          }
        }
      }
      catch (WebException ex) when (ex.Status == WebExceptionStatus.ProtocolError && ex.Response is HttpWebResponse)
      {
        HttpWebResponse response;

        response = (HttpWebResponse)ex.Response;

        switch (response.StatusCode)
        {
          case HttpStatusCode.Unauthorized: throw new SecurityException("Invalid authorization key.", ex);
          case HttpStatusCode.ServiceUnavailable: throw new InvalidOperationException("Quota exceeded.", ex);
          default: throw;
        }
      }
    }

    private Encoding GetResponseEncoding(HttpWebResponse response)
    {
      return string.IsNullOrEmpty(response.CharacterSet) ? Encoding.UTF8 : Encoding.GetEncoding(response.CharacterSet);
    }

    private string GetResponseString(HttpWebResponse response)
    {
      Encoding encoding;
      string result;

      encoding = this.GetResponseEncoding(response);

      using (Stream stream = response.GetResponseStream())
      {
        using (StreamReader reader = new StreamReader(stream, encoding))
        {
          result = reader.ReadToEnd();
        }
      }

      return result;
    }

    private void RefreshToken()
    {
      // https://docs.microsofttranslator.com/oauth-token.html

      if (string.IsNullOrEmpty(_authorizationKey))
      {
        throw new InvalidOperationException("Authorization key not set.");
      }

      this.ExecuteRequest(_issueTokenUri, null, request =>
                                                {
                                                  request.Method = WebRequestMethods.Http.Post;
                                                  request.Headers.Add("Ocp-Apim-Subscription-Key", _authorizationKey);
                                                  request.ContentLength = 0; // Must be set to avoid 411 response
                                                }, response =>
                                                   {
                                                     _authorizationToken = this.GetResponseString(response);
                                                     _timestampWhenTokenExpires = DateTime.UtcNow.AddMinutes(_minutesUntilTokenExpires);
                                                   });
    }

    #endregion
  }
}

Donate

Donate