Easily using Microsoft's Translation API with Python

Microsoft has a translation API. If you're familiar with it, that's probably because you saw that Google charges for theirs and wanted a free option. MS lets you translate two million characters per month for free, and their translations are pretty good! Kudos to you, MS! You can check it out here.

However, their docs for using it are clearly geared to the MS world, and it's kind of ridiculous how much code they want you to use to get your first "Hello World" from "Hallo Welt". After all, you're really just using a simple REST API with OAuth. If you're not building an ASP.net application, the below should be easier to follow than their example.

Simple Python3 version

Gets a token and translates a German string to English

When dealing with translations, Python3's far superior unicode support makes it a much better choice than Python2

# -*- coding: utf-8 -*-
import urllib.request, urllib.error, urllib.parse
import requests
import json
from xml.dom import minidom

clientSecret = "your_client_secret"
clientID = "your_client_id"
strTranslatorAccessURI = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13"

def getToken():
    strRequestDetails = {
        "grant_type":"client_credentials",
        "client_id":clientID,
        "client_secret":clientSecret,
        "scope":"http://api.microsofttranslator.com"
    }
    r = requests.post(strTranslatorAccessURI, data=strRequestDetails)
    token = json.loads(r.text)
    return token

def getText(txtToTranslate, token):
    translations = []
    authString = "Bearer %s" % token['access_token']
    headers = {"Authorization" : authString}
    uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=%s&from=de&to=en" %  txtToTranslate
    r = requests.get(uri, headers=headers)
    xmldoc = minidom.parseString(r.text)
    itemlist = xmldoc.getElementsByTagName('string')

    for item in itemlist:
        for child in item.childNodes:
            translations.append(child.nodeValue)
    return translations

if __name__ == "__main__":
    token = getToken();
    print(getText("Hallo Welt!", token))

Code from MS version

(from http://blogs.msdn.com/b/translation/p/gettingstarted2.aspx):

MS assumes you're writing an ASP.net application and doing everything in response to a button click, which makes for a rather obtuse example. I share some of the code below. Note - don't use it! This is for illustration, not to guide the wayward soul who searched for "Translation API ASP.net" or some such.

Setting an event handler

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace FirstTranslator
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Button1.Click += new EventHandler(Button1_Click);
        }

        void Button1_Click(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }
    }
}

Getting the Access Token

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace FirstTranslator
{
    public class AdmAccessToken
    {
        public string access_token { get; set; }
        public string token_type { get; set; }
        public string expires_in { get; set; }
        public string scope { get; set; }
    } 

    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Button1.Click += new EventHandler(Button1_Click);
        }

        void Button1_Click(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }
    }
}

Assigning stuff to a button

string clientID = "<Your ClientID>";
string clientSecret = "<Your Client Secret>";

String strTranslatorAccessURI = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
String strRequestDetails = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", HttpUtility.UrlEncode(clientID), HttpUtility.UrlEncode(clientSecret));

System.Net.WebRequest webRequest = System.Net.WebRequest.Create(strTranslatorAccessURI);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";

byte[] bytes = System.Text.Encoding.ASCII.GetBytes(strRequestDetails);
webRequest.ContentLength = bytes.Length;
using (System.IO.Stream outputStream = webRequest.GetRequestStream())
{
    outputStream.Write(bytes, 0, bytes.Length);
}
System.Net.WebResponse webResponse = webRequest.GetResponse();

System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(AdmAccessToken));
//Get deserialized object from JSON stream 
AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(webResponse.GetResponseStream());

string headerValue = "Bearer " + token.access_token;

Actually getting your string out of the API

string txtToTranslate = TextBox1.Text;
string uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + System.Web.HttpUtility.UrlEncode(txtToTranslate) + "&from=en&to=es";
System.Net.WebRequest translationWebRequest = System.Net.WebRequest.Create(uri);
translationWebRequest.Headers.Add("Authorization", headerValue);
System.Net.WebResponse response = null;
response = translationWebRequest.GetResponse();
System.IO.Stream stream = response.GetResponseStream();
System.Text.Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
System.IO.StreamReader translatedStream = new System.IO.StreamReader(stream, encode);
System.Xml.XmlDocument xTranslation = new System.Xml.XmlDocument();
xTranslation.LoadXml(translatedStream.ReadToEnd());
lbl1.Text = "Your Translation is: " + xTranslation.InnerText; 

If you actually read this far, I congratulate you.

Tschüss!