none
Passing dataframes as InputParameters to execute REST API in Microsoft R Server 9.0 RRS feed

  • Question

  • Hi,

    I am upgrading our server from 8.0 to 9.0. In v8, we used the DeployR client package to make calls to the R Server. 

    In 9.0, as far as I can see,  the client side code is auto generated using a swagger specification. All parameters have to be serialized into json before sending the http request and output paramters have to be deserialized in the response.

    I was able to get this to work for some data types, but I am not able to get Data Frame's to work due to the server returning a "Message=The type 'JArray' is not supported" error (seen in fiddler on the client side). There is essentially no documentation about how to migrate from 8.0 to 9.0 around upgrading client code to work with the new client code. Any help I can get will be much appreciated. 

    Details:

    My input is a simple dataframe with this content and is built in C# as a List<IList<Object>>

    [

      [ 1.0, 2.0 ]

      ['AAA', 'BBB']

    ]

    The R script CommandText is: 

    var_df <- ip_df\n\nresult <- var_df[1,\"EmpId\"]\nprint (result)",

    The new API takes an ExecuteRequest object which has a list of WorkspaceObject's (built from the dataframe list of list) for input and output parameters. 

     ExecuteRequest req = new ExecuteRequest(CommandText, wrkspcObjects, Outputparams);

    This is then passed to the autogenerated code  (from here: https://msdn.microsoft.com/en-us/microsoft-r/operationalize/app-developer-get-started)

    DeployRClient.cs (generated client side)::ExecuteCodeWithHttpMessagesAsync() ->

    _requestContent = SafeJsonConvert.SerializeObject(executeRequest, SerializationSettings);

     _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false);

    At this point, I get an error back with a 400 Bad Request. When I check this in fiddler, I see an error message attached to the HTTP response code saying

    {"Link":"https://go.microsoft.com/fwlink/?linkid=830136","Message":"The type 'JArray' is not supported"}

    This is an error response coming back from the R Server 9.0 itself, so I am not sure how to debug. I have also tried to change the autogenerated code to use the NewtonSoft json.net serializer instead of the Microsoft Rest json serializer.

    Monday, April 24, 2017 3:31 PM

Answers

  • Hi, i've recently encountered the same problem but managed to marshall a multidimensional array back to R by using a Dictionary<string, ArrayList>. This  doesn't get JSONed as a JArray.

    I've used "Column1", "Column2" etc as the dictionary key.

    Hope this helps.

    • Marked as answer by sehunley Friday, August 31, 2018 6:30 AM
    Sunday, June 18, 2017 6:27 PM

All replies

  • Hi Sehunly.

    I also faced the same issue, but instead of following the scripts prescribed by documentation in MRS 9.0.1 or MRS 9.1, we used old school approach. We created swagger of RserverBase that will have DeployRClient class. You have to properly define endpoint in the code and proper userID / password.

    We started creating sessions and used 'ExecuteCode' function in that session. Also we modified underlying R script to return the output in proper JSON format. Later we deserialized the JSON to our own object.

    It was more easy for us to just add few lines in R Scripts and make things work than the whole swagger thing. Also, we were dependent on session and wanted to upload the data and keep in memory for different request to use, thus this approach.

    Here is sample code that we based whole of our project with:

            private void button_Click(object sender, RoutedEventArgs e)
            {
                RClient = new DeployRClient();
                RClient.BaseUri = new Uri(endpoint);
                AccessTokenResponse loginResponse = RClient.Login(new RServerBase.Models.LoginRequest(username, password) { });
                WorkspaceObject fileName = new WorkspaceObject("fileName", "c:\Sample.csv");
                var headers = RClient.HttpClient.DefaultRequestHeaders;
                var accessToken = loginResponse.AccessToken;
                headers.Remove("Authorization");
                headers.Add("Authorization", $"Bearer {accessToken}");
                CreateSessionRequest sessionreq = new CreateSessionRequest("ss1", null);
                sessionres = RClient.CreateSession(sessionreq);
                            var code = "data<-LoadData(fileName);summary(data)";
                ExecuteResponse response = RClient.ExecuteCode(sessionres.SessionId, new ExecuteRequest(code.ToString(),
                                                                                     new List<WorkspaceObject>() { fileName },
                                                                                     new List<string>() { "data" }));

                WorkspaceObject rowCountWorkSpaceObject =

                                                  response.OutputParameters.Where(s => s.Name == "data").FirstOrDefault();
               

                Dictionary<string, object> Robj1 = ConvertRObjecttoJSON(rowCountWorkSpaceObject);
                JArray a = rowCountWorkSpaceObject.Value as JArray;
                JValue b = a.FirstOrDefault() as JValue;
                string row = b.ToString();
                var columnCount = response.OutputParameters.Where(s => s.Name == "columnCount").FirstOrDefault();

            }

    I removed some code specific to me, so just take the concept than the sample code populated here.

    Thanks,

    Satya


    satyaganti

    Friday, May 12, 2017 9:03 AM
  • Hi, i've recently encountered the same problem but managed to marshall a multidimensional array back to R by using a Dictionary<string, ArrayList>. This  doesn't get JSONed as a JArray.

    I've used "Column1", "Column2" etc as the dictionary key.

    Hope this helps.

    • Marked as answer by sehunley Friday, August 31, 2018 6:30 AM
    Sunday, June 18, 2017 6:27 PM