Skip to Content

Machine Learning affects more and more our life. Also the business focuses more on this kind of automatically learning. That was reasons enough for me to be participant of the terrific openSAP course SAP Leonardo Machine Learning Foundation – An Introduction. After that I did what Dr. Karthik Muthuswamy suggested, I tried it with the favorite language of my choice.

I am a script programmer and I use primarly Microsoft PowerShell. With my first step in this new world I decided to use the Inference Service for Language Detection. The SAP API Business Hub offers at the moment code snippets in a few different languages.

Simple Snippet Implementation

That is very helpful to translate it to PowerShell. Here an equivalent code to detect the language of a text – in our case Swedish.

$Url = "https://sandbox.api.sap.com/ml/languagedetection/language";

$header = New-Object "System.Collections.Generic.Dictionary[[String],[String]]";
$header.Add("Content-Type", "application/json");
$header.Add("APIKey", "InsertYourKeyHere");

$JSON = '{"message":"Hej alla i bussen med de stora hjulen"}';

Try {
  $Result = Invoke-WebRequest -Uri $Url -Method Post `
    -Headers $header -Body $JSON -ErrorVariable RestError;
} Catch {
} Finally {
  If ($Result.StatusCode -eq 200) {
    Write-Host $Result.Content;
  } Else {
    Write-Host $RequestURI $RestError $Result.StatusCode;
  }
}

it works perfect.

Encapsulation in a function

To simplificate the using of the I creat a function CallSAPMLF with the Url and JSON as parameters. On this way it is possible to use this function for any service.

#-Function CallSAPMLF---------------------------------------------------
Function CallSAPMLF {

  Param(
    $Url,
    $JSON
  )

  $header = New-Object "System.Collections.Generic.Dictionary[[String],[String]]";
  $header.Add("Content-Type", "application/json");
  $header.Add("APIKey", "InsertYourKeyHere");

  Try {
    $Result = Invoke-WebRequest -Uri $Url -Method Post `
      -Headers $header -Body $JSON -ErrorVariable RestError;
  } Catch {
  } Finally {
    If ($Result.StatusCode -eq 200) {
      Write-Host $Result.Content;
    } Else {
      Write-Host $RequestURI $RestError $Result.StatusCode;
    }
  }

}

#-Sub Main--------------------------------------------------------------
Function Main {

  $Url = "https://sandbox.api.sap.com/ml/languagedetection/language";
  $JSON = '{"message":"Hallo zusammen im Bus mit den grossen Reifen"}';
  CallSAPMLF -Url $Url -JSON $JSON;

  $Url = "https://sandbox.api.sap.com/ml/languagedetection/language";
  $JSON = '{"message":"Hello together in the bus with the big wheels"}';
  CallSAPMLF -Url $Url -JSON $JSON;

}

#-Main------------------------------------------------------------------
Main;

This works also as expected.

Packed in a UI

Last but not least I developed a tiny UI to input any text for testing. The UI bases on Windows Forms and contains a multiline text field with two buttons.

#-Function GetText------------------------------------------------------
Function GetText {

  Add-Type -AssemblyName System.Windows.Forms;
  Add-Type -AssemblyName System.Drawing;

  $frmText = New-Object System.Windows.Forms.Form;
  $frmText.Text = "Text";
  $frmText.StartPosition = "CenterScreen";
  $frmText.Size = New-Object System.Drawing.Size(500,500);
  $frmText.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle;
  $frmText.MaximizeBox = $False;
  $frmText.MinimizeBox = $False;

  $txt = New-Object System.Windows.Forms.TextBox;
  $txt.Location = New-Object System.Drawing.Point(10,10);
  $txt.Size = New-Object System.Drawing.Size(475,425);
  $txt.Multiline = $True;
  $txt.WordWrap = $True;
  $txt.Font = New-Object System.Drawing.Font("Lucida Console", `
    14, [System.Drawing.FontStyle]::Regular);
  $frmText.Controls.Add($txt);

  $btnOK = New-Object System.Windows.Forms.Button;
  $btnOK.Location = New-Object System.Drawing.Point(10,440);
  $btnOK.Size = New-Object System.Drawing.Size(150,24);
  $btnOK.Text = "Ok";
  $btnOK.DialogResult = [System.Windows.Forms.DialogResult]::OK;
  $frmText.Controls.Add($btnOK);

  $btnCancel = New-Object System.Windows.Forms.Button;
  $btnCancel.Location = New-Object System.Drawing.Point(165,440);
  $btnCancel.Size = New-Object System.Drawing.Size(150,24);
  $btnCancel.Text = "Abbrechen";
  $btnCancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel;
  $frmText.Controls.Add($btnCancel);

  $Result = $frmText.ShowDialog();

  If($Result -eq [System.Windows.Forms.DialogResult]::OK) {
    Return $txt.Text;
  }

}

#-Function CallSAPMLF---------------------------------------------------
Function CallSAPMLF {

  Param(
    $Url,
    $JSON
  )

  $header = New-Object "System.Collections.Generic.Dictionary[[String],[String]]";
  $header.Add("Content-Type", "application/json");
  $header.Add("APIKey", "InsertYourKeyHere");

  Try {
    $Result = Invoke-WebRequest -Uri $Url -Method Post -Headers $header `
      -Body ([System.Text.Encoding]::UTF8.GetBytes($JSON)) -ErrorVariable RestError;
  } Catch {
  } Finally {
    If ($Result.StatusCode -eq 200) {
      Write-Host $Result.Content;
    } Else {
      Write-Host $RequestURI $RestError $Result.StatusCode;
    }
  }

}

#-Sub Main--------------------------------------------------------------
Function Main {

  $Message = GetText;
  If($Message -eq $null) {
    Return;
  }
  $Message = $Message -replace "`r`n", ' ';

  $Url = "https://sandbox.api.sap.com/ml/languagedetection/language";
  $JSON = "{""message"":""$($Message)""}";
  CallSAPMLF -Url $Url -JSON $JSON;

}

#-Main------------------------------------------------------------------
Main;

This works also great. The only difference is that I convert the body input to the http request in UTF8. This is necessary to handle country specific special characters, e.g. like German umlauts ö,ä or ü.

Now we add another text field to get the output direct in the UI and not in the development environment.

#-Global variables------------------------------------------------------
$script:Url = "https://sandbox.api.sap.com/ml/languagedetection/language";

#-Function GUI----------------------------------------------------------
Function GUI {

  Add-Type -AssemblyName System.Windows.Forms;
  Add-Type -AssemblyName System.Drawing;

  [System.Windows.Forms.Application]::EnableVisualStyles()

  $frmText = New-Object System.Windows.Forms.Form;
  $frmText.SuspendLayout();
  $frmText.Text = "Text";
  $frmText.StartPosition = "CenterScreen";
  $frmText.Size = New-Object System.Drawing.Size(510,510);
  $frmText.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle;
  $frmText.MaximizeBox = $False;
  $frmText.MinimizeBox = $False;

  $txt = New-Object System.Windows.Forms.TextBox;
  $txt.Location = New-Object System.Drawing.Point(10,10);
  $txt.Size = New-Object System.Drawing.Size(475,225);
  $txt.Multiline = $True;
  $txt.WordWrap = $True;
  $txt.Name = "txt";
  $txt.Font = New-Object System.Drawing.Font("Lucida Console", `
    14, [System.Drawing.FontStyle]::Regular);
  $frmText.Controls.Add($txt);

  $btnOK = New-Object System.Windows.Forms.Button;
  $btnOK.Location = New-Object System.Drawing.Point(10,240);
  $btnOK.Size = New-Object System.Drawing.Size(150,24);
  $btnOK.Text = "Ok";
  $btnOK.Name = "btnOk";
  $frmText.Controls.Add($btnOK);

  $btnCancel = New-Object System.Windows.Forms.Button;
  $btnCancel.Location = New-Object System.Drawing.Point(165,240);
  $btnCancel.Size = New-Object System.Drawing.Size(150,24);
  $btnCancel.Text = "Abbrechen";
  $btnCancel.Name = "btnCancel";
  $frmText.Controls.Add($btnCancel);

  $txtOut = New-Object System.Windows.Forms.TextBox;
  $txtOut.Location = New-Object System.Drawing.Point(10,270);
  $txtOut.Size = New-Object System.Drawing.Size(475,195);
  $txtOut.Multiline = $True;
  $txtOut.WordWrap = $True;
  $txtOut.Name = "txtOut";
  $txtOut.Font = New-Object System.Drawing.Font("Lucida Console", `
    12, [System.Drawing.FontStyle]::Regular);
  $frmText.Controls.Add($txtOut);

  $btnOK.Add_Click( {
    $txtOut.Clear();
    If($txt.Text) {
      $JSON = "{""message"":""$($txt.Text)""}";
      $ret = CallSAPMLF -Url $script:Url -JSON $JSON | ConvertFrom-Json;
      $txtOut.Text = "Language:      " + $ret.langStr + "`r`n" + `
                     "Language Code: " + $ret.langCode + "`r`n" + `
                     "Confidence:    " + $ret.confidence.ToString("P0");
    }
  })

  $btnCancel.Add_Click( {
    $frmText.Close();
  } )

  [Void]$frmText.ShowDialog();

}

#-Function CallSAPMLF---------------------------------------------------
Function CallSAPMLF {

  Param(
    $Url,
    $JSON
  )

  $header = New-Object "System.Collections.Generic.Dictionary[[String],[String]]";
  $header.Add("Content-Type", "application/json");
  $header.Add("APIKey", "InsertYourKeyHere");

  Try {
    $Result = Invoke-WebRequest -Uri $Url -Method Post -Headers $header `
      -Body ([System.Text.Encoding]::UTF8.GetBytes($JSON)) -ErrorVariable RestError;
  } Catch {
  } Finally {
    If ($Result.StatusCode -eq 200) {
      $Return = $Result.Content;
    } Else {
      $Return = $RequestURI + $RestError + $Result.StatusCode;
    }
  }

  Return $Return;

}

#-Sub Main--------------------------------------------------------------
Function Main {
  GUI;
}

#-Main------------------------------------------------------------------
Main;

That looks much better.

Service Combining

Now we combine the text language detection service with the text translation service. At first we detect the input language and the result we use as input for the text translation service. Therefore I add for the target language a combo box with different language codes.

#-Global variables------------------------------------------------------
$script:Url_Detect = "https://sandbox.api.sap.com/ml/languagedetection/language";
$script:Url_Translate = "https://sandbox.api.sap.com/ml/translation/translation";

#-Function GUI----------------------------------------------------------
Function GUI {

  Add-Type -AssemblyName System.Windows.Forms;
  Add-Type -AssemblyName System.Drawing;

  [System.Windows.Forms.Application]::EnableVisualStyles()

  $frmText = New-Object System.Windows.Forms.Form;
  $frmText.SuspendLayout();
  $frmText.Text = "Text";
  $frmText.StartPosition = "CenterScreen";
  $frmText.Size = New-Object System.Drawing.Size(510,510);
  $frmText.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle;
  $frmText.MaximizeBox = $False;
  $frmText.MinimizeBox = $False;

  $txt = New-Object System.Windows.Forms.TextBox;
  $txt.Location = New-Object System.Drawing.Point(10,10);
  $txt.Size = New-Object System.Drawing.Size(475,225);
  $txt.Multiline = $True;
  $txt.WordWrap = $True;
  $txt.Name = "txt";
  $txt.Font = New-Object System.Drawing.Font("Lucida Console", `
    14, [System.Drawing.FontStyle]::Regular);
  $frmText.Controls.Add($txt);

  $btnOK = New-Object System.Windows.Forms.Button;
  $btnOK.Location = New-Object System.Drawing.Point(10,240);
  $btnOK.Size = New-Object System.Drawing.Size(150,24);
  $btnOK.Text = "Ok";
  $btnOK.Name = "btnOk";
  $frmText.Controls.Add($btnOK);

  $btnCancel = New-Object System.Windows.Forms.Button;
  $btnCancel.Location = New-Object System.Drawing.Point(165,240);
  $btnCancel.Size = New-Object System.Drawing.Size(150,24);
  $btnCancel.Text = "Abbrechen";
  $btnCancel.Name = "btnCancel";
  $frmText.Controls.Add($btnCancel);

  $TargetLang = @("de","en","it","fr");
  $cboTargetLang = New-Object System.Windows.Forms.ComboBox;
  $cboTargetLang.Location = New-Object System.Drawing.Point(435,240);
  $cboTargetLang.Size = New-Object System.Drawing.Size(50,50);
  ForEach($Lang In $TargetLang) {
    [Void]$cboTargetLang.Items.Add($Lang);
  }
  $cboTargetLang.SelectedText = "de";
  $frmText.Controls.Add($cboTargetLang);

  $txtOut = New-Object System.Windows.Forms.TextBox;
  $txtOut.Location = New-Object System.Drawing.Point(10,270);
  $txtOut.Size = New-Object System.Drawing.Size(475,195);
  $txtOut.Multiline = $True;
  $txtOut.WordWrap = $True;
  $txtOut.Name = "txtOut";
  $txtOut.Font = New-Object System.Drawing.Font("Lucida Console", `
    12, [System.Drawing.FontStyle]::Regular);
  $frmText.Controls.Add($txtOut);

  $btnOK.Add_Click( {
    $txtOut.Clear();
    If([String]::IsNullOrEmpty($txt.Text)) {
      Return;
    }
    $JSON = "{""message"":""$($txt.Text)""}";
    $ret = CallSAPMLF -Url $script:Url_Detect -JSON $JSON | ConvertFrom-Json;
    If($ret.langCode -eq $cboTargetLang.Text) {
      $txtOut.Text = $txt.Text;
    } Else {
      $JSON = "{""sourceLanguage"":""$($ret.langCode)""," + `
        """targetLanguages"":[""$($cboTargetLang.Text)""]," + `
        """units"":[{""value"":""$($txt.Text)""}]}";
      $ret = CallSAPMLF -Url $script:Url_Translate -JSON $JSON | ConvertFrom-Json;
      $txtOut.Text = $ret.units.translations.value;
      }
  })

  $btnCancel.Add_Click( {
    $frmText.Close();
  } )

  [Void]$frmText.ShowDialog();

}

#-Function CallSAPMLF---------------------------------------------------
Function CallSAPMLF {

  Param(
    $Url,
    $JSON
  )

  $header = New-Object "System.Collections.Generic.Dictionary[[String],[String]]";
  $header.Add("Content-Type", "application/json");
  $header.Add("APIKey", "InsertYourKeyHere");

  Try {
    $Result = Invoke-WebRequest -Uri $Url -Method Post -Headers $header `
      -Body ([System.Text.Encoding]::UTF8.GetBytes($JSON)) -ErrorVariable RestError;
  } Catch {
  } Finally {
    If ($Result.StatusCode -eq 200) {
      $Return = $Result.Content;
    } Else {
      $Return = $RequestURI + $RestError + $Result.StatusCode;
    }
  }

  Return $Return;

}

#-Sub Main--------------------------------------------------------------
Function Main {
  GUI;
}

#-Main------------------------------------------------------------------
Main;

Great, on this way it is very easy to implement this kind of translation application.

Conclusion

It is very simple to use the SAP API Business Hub with PowerShell as you can see. You can integrate the calls seamlessly. Thanks to SAP for this possibility.

 

Do you remember the Swedish Chef from the Muppets?

At the beginning he sang a tiny song with this words:
Yorn desh born, der ritt de gitt der gue,
Orn desh, dee born desh, de umn bork! bork! bork!

If I try these words with the language detection service I get an surprising result. Try it by yourself…

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply