Building Web Services with R and Azure ML

This post is by Raymond Laghaeian, a Senior Program Manager on Microsoft Azure Machine Learning.

The support for R in Azure ML allows you to easily integrate existing R scripts into an experiment. From there, you are just a couple of clicks away to publishing your script as a web service. In this post, we walk you through the steps needed to accomplish that. We will then consume the resulting web service in an ASP.NET web application.

Create New Experiment

First, we create a new experiment by clicking on “+New” in the Azure ML Studio and selecting Blank Experiment. We then drag the Execute R module and add it to the experiment, as shown below:


Figure 1: Execute R module added to the experiment

Add the Script

We next click in the R Script Property in the right pane, delete the existing sample code, and paste the following script:

a = c("name", "Joe", "Lisa")

b = c("age", "20", "21")

c = c("married", TRUE, FALSE)

df = data.frame(a, b, c)

#Select the second row

data.set = df[2,]

# Return the selected row as output

maml.mapOutputPort("data.set");

The resulting experiment looks as follows:


Figure 2: Adding R script to the module

Publish the Web Service

To publish this as a web service, we drag the Web service output from the lower left pane and attach it to the right output of the Execute R Script module. You can use the Web Service view switch to toggle between experiment and web service flows.


Figure 3: Web Service Setup

 

We next click Run, and upon completion, click the Publish Web Service button when it becomes enabled (bottom of the screen). We next click Yes twice to publish the web service.

After the Web Service is published, its Dashboard will be displayed with the API Key and a Test link to call the Request Response Service (RRS):

 
Figure 4: Web Service Dashboard 

Test the Web Service

To test the web service, we click on the Test link for the Request Response service, and on the checkmark on the dialog (“This web service does not require any input”).

Note the result on the bottom of the screen. Clicking the Details button will show the row we had selected in the dataset returned in the API response.

 
Figure 5: Web Service call result showing R script output 

Create an ASP.Net Client

To consume the web service in an ASP.Net web application, we start Visual Studio and create a new ASP.Net Web Application (File -> New Project -> ASP.Net Web Application). In the Name field, we type in R Web Service Client.


Figure 6: Create an ASP.NET Web Application project

 

In the new ASP.NET Project window, we select Web Forms, then click OK.

Next, in the Solution Explorer window, we right click on the project name (R Web Service Client) and add a new Web Form. When prompted for the name, we name it CallR.

Set Up the UI

In CallR.aspx, we paste the following code in the <div> tag (between <div> and <div/>).

 <h1>R Web Service client</h1>

        <asp:Label ID="Label2" runat="server" Text="Click to call R web service"></asp:Label><br />

        <asp:Button ID="Button1" runat="server" Text="Call Web service" OnClick="Button1_Click" /><br />

        <p />

        <asp:Label ID="Label1" runat="server" Text=""></asp:Label>

Setup the Code to Call Your Web Service

The code for this section is copied from the C# sample code on the API help page for RRS (see Figure 4 above) with some modifications for ASP.NET. First, as described at the top of the sample C# code, we install Microsoft.AspNet.WebApi.Client. We then add the following “using” statements:

using System.Net.Http;

using System.Net.Http.Formatting;

using System.Net.Http.Headers;

using System.Text;

using System.Threading.Tasks;

Next, in the code view of the page (CallR.aspx.cs), we add a button-click event:

protected void Button1_Click(object sender, EventArgs e)

        {

            InvokeRequestResponseService().Wait();

        }

We next add the following method below the Button1_Click event.

async Task InvokeRequestResponseService()

        {

            using (var client = new HttpClient())

            {

                ScoreData scoreData = new ScoreData()

                {

                    FeatureVector = new Dictionary<string, string>() {},

                    GlobalParameters = new Dictionary<string, string>(){}

                };

                ScoreRequest scoreRequest = new ScoreRequest()

                {

                    Id = "score00001",

                    Instance = scoreData

                };

                //Set the API key (Use API key for your web service – see Firgure 4)

                const string apiKey = "a4C/IkyCy6N4Gm80aF6A==";

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);

                client.BaseAddress = new Uri("https://ussouthcentral.services.azureml.net/workspaces/b3692371e94aa5bec7a28889/services/874c7886a2453d947113e48c1d/score");//Replace with your web service URL from C# Sample code of the API help page for RRS

                HttpResponseMessage response = await client.PostAsJsonAsync("", scoreRequest).ConfigureAwait(false);

                if (response.IsSuccessStatusCode)

                {

                    string result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                    Label1.Text = "Result: " + result;

                }

                else

                {

                    Label1.Text = "Failed with status code: " + response.StatusCode;

                }

            }

        }

 Finally, add the following two classes after the Partial Class CallR.

    public class ScoreData

    {

        public Dictionary<string, string> FeatureVector { get; set; }

        public Dictionary<string, string> GlobalParameters { get; set; }

    }

   public class ScoreRequest

    {

        public string Id { get; set; }

        public ScoreData Instance { get; set; }

    }

The class should now look like this:

Run the Application

We then run the application (F5) and click on the Call Web Service button to get the results:

If you got this far, we hope you enjoyed reading this post! To quickly summarize, using Azure ML, it is easy to create a web service from an R script and consume it in an ASP.NET web application – just as this example demonstrated.

Raymond
Contact me on twitter. Get started with Azure ML at the Machine Learning Center.