I’m currently involved in an IoT project where we have to call a number of R-models hosted in Azure Machine Learning.
This post is not about publishing the models and calling the endpoints; this is pretty straight forward.
Rather this post is about utilizing the Management REST APIs.
I initially had problems with the authentication. To authenticate towards the endpoint (both the model and the management) you have to set the Authentication header to a JSON Web Token.
The following is a short guide on how to get everything working.
The first thing you have to find out is if your Azure ML endpoints are hosted the old/classic way or the new way.
- If the former the security token can be found in Azure ML Studio under Settings for the given model.
- If the later you need to create an AAD token.
For a number of reasons I have my endpoints hosted the new way, hence the need to get an AAD token. This can be a little tricky if you have never done it before.
- Create a new app in AAD. For instructions see Use portal to create an Azure Active Directory application and service principal that can access resources. You can point it to https://management.azure.com/ This is less important.
- Get the Client Id (called the App Id) and the Secret (called the key).
- Using the Microsoft.IdentityModel.Clients.ActiveDirectory namespace – also the name of the nuget package – you can request a token which you can place in the Authentication header and call the management REST API.
That is really all there is to it.
A small code example is given below.
// Constants var addInstance = "https://login.microsoftonline.com/{0}"; var tenant = "Contoso.onmicrosoft.com" var authority = String.Format(CultureInfo.InvariantCulture, addInstance, tenant); var clientId = "[Your Client Id]"; var appKey = "[The App Key]" var subscriptionid = "[Your Azure Subscription Id]"; var resourceGroupName = "[Resource Group that hosts the Machine Learning workspace]"; // Create Authentication Context var authContext = new AuthenticationContext(authority); var clientCredential = new ClientCredential(clientId, appKey); // Get Security Token var azureMlResourceId = "https://management.azure.com/"; var result = await authContext.AcquireTokenAsync(azureMlResourceId, clientCredential); var token = result.AccessToken; var client = new HttpClient(); var address = $"subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MachineLearning/webServices?api-version=2016-05-01-preview"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); var response = await client.GetAsync(endpoint + address); if (response.IsSuccessStatusCode) { // Do stuff }
On a side note I should mention, that my solution is running inside Azure Service Fabric. I have Services and Actors call a library handling the actual communication that is making the REST call. I had to install the nuget packet in BOTH the library and the Service/Actor, otherwise I got an initialization error when trying to create the AuthenticationContext.