├── LICENSE ├── .Rbuildignore ├── data └── allsorts.rda ├── tests ├── testthat.R └── testthat │ ├── test-buildURL.R │ └── test-buildBody.R ├── .travis.yml ├── data-raw ├── allsorts.csv ├── allsorts.R └── getResp.R ├── NAMESPACE ├── .gitignore ├── man ├── azuremlweb.Rd ├── parseResponse.Rd ├── parseDataFrame.Rd ├── buildBody.Rd ├── separateDataFrame.Rd ├── allsorts.Rd ├── buildURL.Rd ├── makeRequest.Rd └── azuremlService.Rd ├── DESCRIPTION ├── R ├── azuremlweb-package.R ├── buildURL.R ├── buildBody.R ├── parseResponse.R ├── makeRequest.R └── azuremlService.R └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2016 2 | COPYRIGHT HOLDER: Mango Solutions 3 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^\.travis\.yml$ 4 | ^data-raw$ 5 | -------------------------------------------------------------------------------- /data/allsorts.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangoTheCat/azuremlweb/master/data/allsorts.rda -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(azuremlweb) 3 | 4 | test_check("azuremlweb") 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | 3 | language: R 4 | sudo: false 5 | cache: packages 6 | -------------------------------------------------------------------------------- /data-raw/allsorts.csv: -------------------------------------------------------------------------------- 1 | "Fac","Num","Int","Intish","Date","Char","TimeStamp" 2 | "A",1.1,1,1,2016-05-01,"iam",2016-05-14 21:00:03 3 | "B",2.2,2,2,2016-05-02,"a",2016-05-14 21:00:04 4 | "C",3.3,3,3,2016-05-03,"fish",2016-05-14 21:00:05 5 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(azuremlService) 4 | export(buildBody) 5 | export(buildURL) 6 | export(makeRequest) 7 | export(parseDataFrame) 8 | export(parseResponse) 9 | export(separateDataFrame) 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Session Data files 6 | .RData 7 | # Example code in package build process 8 | *-Ex.R 9 | # RStudio files 10 | .Rproj.user/ 11 | azuremlweb.Rproj 12 | # produced vignettes 13 | vignettes/*.html 14 | vignettes/*.pdf 15 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 16 | .httr-oauth 17 | .Rproj.user 18 | -------------------------------------------------------------------------------- /man/azuremlweb.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/azuremlweb-package.R 3 | \docType{package} 4 | \name{azuremlweb} 5 | \alias{azuremlweb} 6 | \alias{azuremlweb-package} 7 | \title{azuremlweb: Call an AzureML web service} 8 | \description{ 9 | Makes it easier to test out a new AzureML web service. This package helps 10 | you make a POST request to an AzureML API and parse the response back into R 11 | data frames. 12 | } 13 | 14 | -------------------------------------------------------------------------------- /man/parseResponse.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/parseResponse.R 3 | \name{parseResponse} 4 | \alias{parseResponse} 5 | \title{Extract data frames from httr response} 6 | \usage{ 7 | parseResponse(resp) 8 | } 9 | \arguments{ 10 | \item{resp}{The httr response object} 11 | } 12 | \value{ 13 | A list of data frames, one for each output from the web service 14 | } 15 | \description{ 16 | Extract data frames from httr response 17 | } 18 | 19 | -------------------------------------------------------------------------------- /man/parseDataFrame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/parseResponse.R 3 | \name{parseDataFrame} 4 | \alias{parseDataFrame} 5 | \title{Extract one data frame from the} 6 | \usage{ 7 | parseDataFrame(result) 8 | } 9 | \arguments{ 10 | \item{result}{an element of the response object that corresponds to a single data frame} 11 | } 12 | \value{ 13 | A data frame typed according to the ColumnTypes element 14 | } 15 | \description{ 16 | Extract one data frame from the 17 | } 18 | 19 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: azuremlweb 2 | Title: Call an AzureML web service 3 | Version: 0.0.0.9000 4 | Authors@R: person("Douglas", "Ashton", email = "dashton@mango-solutions.com", role = c("aut", "cre")) 5 | Description: Makes it easier to test out a new AzureML web service. This package helps you make a POST request to an AzureML API and parse the response back into R data frames. 6 | Depends: 7 | R (>= 3.0.0) 8 | License: MIT + file LICENSE 9 | Encoding: UTF-8 10 | Imports: 11 | httr 12 | RoxygenNote: 5.0.1 13 | Suggests: testthat 14 | -------------------------------------------------------------------------------- /tests/testthat/test-buildURL.R: -------------------------------------------------------------------------------- 1 | context("Request URL") 2 | 3 | test_that("Calling the right URL", { 4 | 5 | expect_equal(buildURL(region = "ussouthcentral", 6 | workspace = "8550bbba99572fc47e18e5fdd53e43e2", 7 | service = "4e7ebd7ad816cd9dd1cb1b17c4cdb0c7", 8 | details = TRUE), 9 | "https://ussouthcentral.services.azureml.net/workspaces/8550bbba99572fc47e18e5fdd53e43e2/services/4e7ebd7ad816cd9dd1cb1b17c4cdb0c7/execute?api-version=2.0&details=true") 10 | 11 | }) 12 | -------------------------------------------------------------------------------- /data-raw/allsorts.R: -------------------------------------------------------------------------------- 1 | # Make a data frame with all sorts of types 2 | 3 | allsorts <- data.frame(Fac = factor(LETTERS[1:3]), 4 | Num = c(1.1, 2.2, 3.3), 5 | Int = c(1L, 2L, 3L), 6 | Intish = 1:3, 7 | Date = as.Date(16922:16924, origin = "1970-01-01"), 8 | Char = c("iam", "a", "fish"), 9 | TimeStamp = as.POSIXct(1463259602 + 1:3, origin="1970-01-01", tz = "UTC")) 10 | 11 | use_data(allsorts, overwrite = TRUE) 12 | write.csv(allsorts, file = "data-raw/allsorts.csv", row.names = FALSE) 13 | -------------------------------------------------------------------------------- /man/buildBody.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/buildBody.R 3 | \name{buildBody} 4 | \alias{buildBody} 5 | \title{Build the body of the request} 6 | \usage{ 7 | buildBody(datasets) 8 | } 9 | \arguments{ 10 | \item{datasets}{A named list of data frames to send to the web service. 11 | The names must match the names of the web inputs in Azure, eg. list(WebInput = data.frame(x=1, y=2))} 12 | } 13 | \value{ 14 | A list ready for converting the JSON 15 | } 16 | \description{ 17 | Build the body of the request 18 | } 19 | \examples{ 20 | buildBody(list(WebInput = data.frame(x=1:5, y=LETTERS[1:5]))) 21 | } 22 | 23 | -------------------------------------------------------------------------------- /man/separateDataFrame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/buildBody.R 3 | \name{separateDataFrame} 4 | \alias{separateDataFrame} 5 | \title{Separate a dataset into the list structure required for the POST request} 6 | \usage{ 7 | separateDataFrame(dataset) 8 | } 9 | \arguments{ 10 | \item{dataset}{A data.frame} 11 | } 12 | \value{ 13 | list with the ColumnNames (char vector) and Values (char matrix) 14 | } 15 | \description{ 16 | The values of the dataset are converted to a matrix. The column names are 17 | stored in a separte list item 18 | } 19 | \examples{ 20 | separateDataFrame(data.frame(x=1:5, y=LETTERS[1:5])) 21 | } 22 | 23 | -------------------------------------------------------------------------------- /man/allsorts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/azuremlweb-package.R 3 | \docType{data} 4 | \name{allsorts} 5 | \alias{allsorts} 6 | \title{A data frame with lots of types in it} 7 | \format{A data frame with 3 rows and 7 variables: 8 | \describe{ 9 | \item{Fac}{A factor variable with levels A,B and C} 10 | \item{Num}{Floating point number} 11 | \item{Int}{Strict R integers} 12 | \item{Intish}{Same as Int but not defined using 1L etc} 13 | \item{Date}{Standard R date} 14 | \item{Char}{Character data} 15 | \item{TimeStamp}{POSIXct stamps} 16 | }} 17 | \source{ 18 | Simulated 19 | } 20 | \usage{ 21 | allsorts 22 | } 23 | \description{ 24 | For use testing whether types are being converted correctly 25 | } 26 | \keyword{datasets} 27 | 28 | -------------------------------------------------------------------------------- /man/buildURL.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/buildURL.R 3 | \name{buildURL} 4 | \alias{buildURL} 5 | \title{Build an AzureML service URL from workspace info} 6 | \usage{ 7 | buildURL(region, workspace, service, details = TRUE) 8 | } 9 | \arguments{ 10 | \item{region}{The Azure region, such as ussouthcentral, europewest} 11 | 12 | \item{workspace}{The workspace ID} 13 | 14 | \item{service}{The service ID} 15 | 16 | \item{details}{Logical. Should be TRUE for now} 17 | } 18 | \value{ 19 | the url as a character 20 | } 21 | \description{ 22 | Build an AzureML service URL from workspace info 23 | } 24 | \examples{ 25 | buildURL(region = "ussouthcentral", 26 | workspace = "8550bbba99572fc47e18e5fdd53e43e2", 27 | service = "4e7ebd7ad816cd9dd1cb1b17c4cdb0c7", 28 | details = TRUE) 29 | } 30 | 31 | -------------------------------------------------------------------------------- /R/azuremlweb-package.R: -------------------------------------------------------------------------------- 1 | #' azuremlweb: Call an AzureML web service 2 | #' 3 | #' Makes it easier to test out a new AzureML web service. This package helps 4 | #' you make a POST request to an AzureML API and parse the response back into R 5 | #' data frames. 6 | #' 7 | #' 8 | #' @docType package 9 | #' @name azuremlweb 10 | NULL 11 | 12 | #' A data frame with lots of types in it 13 | #' 14 | #' For use testing whether types are being converted correctly 15 | #' 16 | #' @format A data frame with 3 rows and 7 variables: 17 | #' \describe{ 18 | #' \item{Fac}{A factor variable with levels A,B and C} 19 | #' \item{Num}{Floating point number} 20 | #' \item{Int}{Strict R integers} 21 | #' \item{Intish}{Same as Int but not defined using 1L etc} 22 | #' \item{Date}{Standard R date} 23 | #' \item{Char}{Character data} 24 | #' \item{TimeStamp}{POSIXct stamps} 25 | #' } 26 | #' @source Simulated 27 | "allsorts" 28 | -------------------------------------------------------------------------------- /R/buildURL.R: -------------------------------------------------------------------------------- 1 | #' Build an AzureML service URL from workspace info 2 | #' 3 | #' @param region The Azure region, such as ussouthcentral, europewest 4 | #' @param workspace The workspace ID 5 | #' @param service The service ID 6 | #' @param details Logical. Should be TRUE for now 7 | #' 8 | #' @return the url as a character 9 | #' @export 10 | #' 11 | #' @examples 12 | #' buildURL(region = "ussouthcentral", 13 | #' workspace = "8550bbba99572fc47e18e5fdd53e43e2", 14 | #' service = "4e7ebd7ad816cd9dd1cb1b17c4cdb0c7", 15 | #' details = TRUE) 16 | buildURL <- function(region, workspace, service, details = TRUE) { 17 | 18 | # Checks 19 | stopifnot(is.logical(details)) 20 | details <- ifelse(details, "true", "false") 21 | 22 | paste0("https://", region, ".services.azureml.net/workspaces/", 23 | workspace, "/services/", service, "/execute?api-version=2.0&details=", details) 24 | } 25 | -------------------------------------------------------------------------------- /data-raw/getResp.R: -------------------------------------------------------------------------------- 1 | data(allsorts) 2 | 3 | resp <- makeRequest(list(Input1=data.frame(Month = 4, OriginAirportID = 14122, Carrier = "AS"), 4 | Input2=allsorts), 5 | url = "https://ussouthcentral.services.azureml.net/workspaces/4a06ac88d985464f9e7b1c14594ce5c0/services/9f72f85b9e344a5184f8d20337c2f33e/execute?api-version=2.0&details=true", 6 | auth="") 7 | 8 | parseResponse(resp) 9 | 10 | 11 | # Single Input Service ---------------------------------------------------- 12 | 13 | resp <- makeRequest(list(Input1=data.frame(Month = 4, OriginAirportID = 14122, Carrier = "AS")), 14 | url = "https://ussouthcentral.services.azureml.net/workspaces/4a06ac88d985464f9e7b1c14594ce5c0/services/6ed02c968b014990a08e1448433b73ce/execute?api-version=2.0&details=true", 15 | auth="") 16 | 17 | parseResponse(resp) 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/testthat/test-buildBody.R: -------------------------------------------------------------------------------- 1 | context("Request body") 2 | 3 | test_that("Multiple inputs work", { 4 | 5 | data("allsorts") 6 | 7 | expect_equal(buildBody(list(Input1=data.frame(Month = 4, OriginAirportID = 14122, Carrier = "AS"), 8 | Input2=allsorts)), 9 | 10 | structure(list(Inputs = structure(list(Input1 = structure(list( 11 | ColumnNames = c("Month", "OriginAirportID", "Carrier"), Values = structure(c("4", 12 | "14122", "AS"), .Dim = c(1L, 3L))), .Names = c("ColumnNames", 13 | "Values")), Input2 = structure(list(ColumnNames = c("Fac", "Num", 14 | "Int", "Intish", "Date", "Char", "TimeStamp"), Values = structure(c("A", 15 | "B", "C", "1.1", "2.2", "3.3", "1", "2", "3", "1", "2", "3", 16 | "2016-05-01", "2016-05-02", "2016-05-03", "iam", "a", "fish", 17 | "2016-05-14 21:00:03 UTC", "2016-05-14 21:00:04 UTC", "2016-05-14 21:00:05 UTC" 18 | ), .Dim = c(3L, 7L))), .Names = c("ColumnNames", "Values"))), .Names = c("Input1", 19 | "Input2"))), .Names = "Inputs")) 20 | }) -------------------------------------------------------------------------------- /man/makeRequest.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/makeRequest.R 3 | \name{makeRequest} 4 | \alias{makeRequest} 5 | \title{Make a POST request to AzureML service} 6 | \usage{ 7 | makeRequest(datasets, url = NULL, region = "ussouthcentral", 8 | workspace = NULL, service = NULL, auth = NULL, details = TRUE) 9 | } 10 | \arguments{ 11 | \item{datasets}{A named list of data frames to send to the web service. 12 | The names must match the names of the web inputs in Azure, eg. list(WebInput = data.frame(x=1, y=2))} 13 | 14 | \item{url}{If you supply the full URL then other options are not required} 15 | 16 | \item{region}{The Azure region, such as ussouthcentral, europewest} 17 | 18 | \item{workspace}{The workspace ID} 19 | 20 | \item{service}{The service ID} 21 | 22 | \item{auth}{Authentication token. Careful not to save this anywhere and 23 | check your .Rhistory} 24 | 25 | \item{details}{Logical. If FALSE then column types are omitted from the 26 | response} 27 | } 28 | \value{ 29 | An httr response object 30 | } 31 | \description{ 32 | Make a POST request to AzureML service 33 | } 34 | \examples{ 35 | \dontrun{ 36 | makeRequest(list(WebInput = data.frame(x=1:5, y=LETTERS[1:5])), 37 | region = "ussouthcentral", 38 | workspace = "8550bbba99572fc47e18e5fdd53e43e2", 39 | service = "4e7ebd7ad816cd9dd1cb1b17c4cdb0c7", 40 | auth = "xxxxxxxxxxxx==") 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /man/azuremlService.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/azuremlService.R 3 | \name{azuremlService} 4 | \alias{azuremlService} 5 | \title{Make a POST request to AzureML service and parse the reponse} 6 | \usage{ 7 | azuremlService(datasets, url = NULL, region = "ussouthcentral", 8 | workspace = NULL, service = NULL, auth = NULL, details = TRUE) 9 | } 10 | \arguments{ 11 | \item{datasets}{A named list of data frames to send to the web service. 12 | The names must match the names of the web inputs in Azure, eg. list(WebInput = data.frame(x=1, y=2))} 13 | 14 | \item{url}{If you supply the full URL then other options are not required} 15 | 16 | \item{region}{The Azure region, such as ussouthcentral, europewest} 17 | 18 | \item{workspace}{The workspace ID} 19 | 20 | \item{service}{The service ID} 21 | 22 | \item{auth}{Authentication token. Careful not to save this anywhere and 23 | check your .Rhistory} 24 | 25 | \item{details}{Logical. If FALSE then column types are omitted from the 26 | response} 27 | } 28 | \value{ 29 | An httr response object 30 | } 31 | \description{ 32 | Make a POST request to AzureML service and parse the reponse 33 | } 34 | \examples{ 35 | \dontrun{ 36 | azuremlService(list(WebInput = data.frame(x=1:5, y=LETTERS[1:5])), 37 | region = "ussouthcentral", 38 | workspace = "8550bbba99572fc47e18e5fdd53e43e2", 39 | service = "4e7ebd7ad816cd9dd1cb1b17c4cdb0c7", 40 | auth = "xxxxxxxxxxxx==") 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /R/buildBody.R: -------------------------------------------------------------------------------- 1 | 2 | #' Build the body of the request 3 | #' 4 | #' @param datasets A named list of data frames to send to the web service. 5 | #' The names must match the names of the web inputs in Azure, eg. list(WebInput = data.frame(x=1, y=2)) 6 | #' 7 | #' @return A list ready for converting the JSON 8 | #' @export 9 | #' 10 | #' @examples 11 | #' buildBody(list(WebInput = data.frame(x=1:5, y=LETTERS[1:5]))) 12 | buildBody <- function(datasets) { 13 | 14 | 15 | values <- as.matrix(datasets[[1]]) 16 | dimnames(values) <- NULL 17 | 18 | req <- list(Inputs = lapply(datasets, separateDataFrame)) 19 | req 20 | } 21 | 22 | #' Separate a dataset into the list structure required for the POST request 23 | #' 24 | #' The values of the dataset are converted to a matrix. The column names are 25 | #' stored in a separte list item 26 | #' 27 | #' @param dataset A data.frame 28 | #' 29 | #' @return list with the ColumnNames (char vector) and Values (char matrix) 30 | #' @export 31 | #' 32 | #' @examples 33 | #' separateDataFrame(data.frame(x=1:5, y=LETTERS[1:5])) 34 | separateDataFrame <- function(dataset) { 35 | # Might need to pass options to charConvertColumn 36 | values <- do.call("cbind", lapply(dataset, charConvertColumn)) 37 | dimnames(values) <- NULL 38 | 39 | list(ColumnNames=names(dataset), 40 | Values = values) 41 | } 42 | 43 | #' Controlled conversion of vectors to characer vectors 44 | #' 45 | #' @param x A vector 46 | #' 47 | #' @return Character vector 48 | #' 49 | charConvertColumn <- function(x) { 50 | switch(class(x)[1], 51 | "POSIXct" = format(x, "%Y-%m-%d %H:%M:%S %Z"), 52 | as.character(x)) 53 | } 54 | -------------------------------------------------------------------------------- /R/parseResponse.R: -------------------------------------------------------------------------------- 1 | 2 | #' Extract data frames from httr response 3 | #' 4 | #' @param resp The httr response object 5 | #' 6 | #' @return A list of data frames, one for each output from the web service 7 | #' @export 8 | #' 9 | parseResponse <- function(resp) { 10 | 11 | respList <- httr::content(resp) 12 | 13 | results <- respList$Results 14 | 15 | lapply(results, parseDataFrame) 16 | 17 | } 18 | 19 | #' Extract one data frame from the 20 | #' 21 | #' @param result an element of the response object that corresponds to a single data frame 22 | #' 23 | #' @return A data frame typed according to the ColumnTypes element 24 | #' @export 25 | #' 26 | parseDataFrame <- function(result) { 27 | 28 | if(result$type != "table") stop("All results must be tables (data.frames)") 29 | 30 | result <- result$value 31 | 32 | output <- list() 33 | for(i in 1:(length(result$ColumnNames))) { 34 | # Do something with the NULLs? 35 | 36 | # Extract the character vector 37 | x <- vapply(result$Values, function(x) x[[i]], "") 38 | # Use the type to convert it 39 | if(!is.null(result$ColumnTypes)) { 40 | x <- switch(result$ColumnTypes[[i]], 41 | "Double" = as.numeric(x), 42 | "String" = x, 43 | "Int32" = as.integer(x), 44 | "Int64" = as.numeric(x), 45 | "Categorical" = factor(x), 46 | "Numeric" = as.numeric(x), 47 | x) 48 | } 49 | # Attach to the 50 | output[[result$ColumnNames[[i]]]] <- x 51 | } 52 | output <- as.data.frame(output, stringsAsFactors = FALSE) 53 | 54 | output 55 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # azuremlweb 2 | 3 | [![Project Status: WIP - Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](http://www.repostatus.org/badges/latest/wip.svg)](http://www.repostatus.org/#wip) 4 | [![Travis-CI Build Status](https://travis-ci.org/MangoTheCat/azuremlweb.svg?branch=master)](https://travis-ci.org/MangoTheCat/azuremlweb) 5 | 6 | Call an AzureML web service from R 7 | 8 | Please please be careful with your API tokens (the numbers below are randomly generated to look like what you get with an Azure service) 9 | 10 | 11 | ```r 12 | # Use your numbers (below are not real numbers) 13 | # Be careful where you put your auth tokens 14 | result <- azuremlService(list(WebInput = data.frame(x=1:5, y=LETTERS[1:5])), 15 | region = "ussouthcentral", 16 | workspace = "8550bbba99572fc47e18e5fdd53e43e2", 17 | service = "4e7ebd7ad816cd9dd1cb1b17c4cdb0c7", 18 | auth = "YTHDwNeuZbQLWHjOEKzMWjVihThTcmsIdRRFkSsvHaFoxZcKTjdFmFPaIsfN+OEdoZlGttMJQrzUPOvvLeCej==") 19 | 20 | httr::content(resp) 21 | ``` 22 | OR 23 | 24 | ```r 25 | result <- azuremlService(list(WebInput = data.frame(x=1:5, y=LETTERS[1:5])), 26 | url = "https://ussouthcentral.services.azureml.net/workspaces/8550bbba99572fc47e18e5fdd53e43e2/services/4e7ebd7ad816cd9dd1cb1b17c4cdb0c7/execute?api-version=2.0&details=true", 27 | auth = "YTHDwNeuZbQLWHjOEKzMWjVihThTcmsIdRRFkSsvHaFoxZcKTjdFmFPaIsfN+OEdoZlGttMJQrzUPOvvLeCej==") 28 | 29 | ``` 30 | 31 | The result is a named list of data frames. This is because you can have multiple outputs from AzureML services. 32 | 33 | ## License 34 | 35 | MIT © Mango Solutions 36 | 37 | -------------------------------------------------------------------------------- /R/makeRequest.R: -------------------------------------------------------------------------------- 1 | 2 | #' Make a POST request to AzureML service 3 | #' 4 | #' @param datasets A named list of data frames to send to the web service. 5 | #' The names must match the names of the web inputs in Azure, eg. list(WebInput = data.frame(x=1, y=2)) 6 | #' @param url If you supply the full URL then other options are not required 7 | #' @param region The Azure region, such as ussouthcentral, europewest 8 | #' @param workspace The workspace ID 9 | #' @param service The service ID 10 | #' @param auth Authentication token. Careful not to save this anywhere and 11 | #' check your .Rhistory 12 | #' @param details Logical. If FALSE then column types are omitted from the 13 | #' response 14 | #' 15 | #' @return An httr response object 16 | #' @export 17 | #' 18 | #' @examples 19 | #' \dontrun{ 20 | #' makeRequest(list(WebInput = data.frame(x=1:5, y=LETTERS[1:5])), 21 | #' region = "ussouthcentral", 22 | #' workspace = "8550bbba99572fc47e18e5fdd53e43e2", 23 | #' service = "4e7ebd7ad816cd9dd1cb1b17c4cdb0c7", 24 | #' auth = "xxxxxxxxxxxx==") 25 | #' } 26 | makeRequest <- function(datasets, url = NULL, region = "ussouthcentral", 27 | workspace=NULL, service=NULL, auth = NULL, details = TRUE) { 28 | 29 | if(is.null(url)) { 30 | url <- buildURL(region, workspace, service, details) 31 | } 32 | 33 | # Build the request list. The names must match the names of the web inputs in Azure 34 | req <- buildBody(datasets) 35 | 36 | if(is.null(auth)) { 37 | auth <- Sys.getenv("AZUREML_APIKEY") 38 | if(auth=="") { 39 | stop("Either set the AZUREML_APIKEY environment variable or pass auth token") 40 | } 41 | } 42 | auth <- paste("Bearer", auth, sep = " ") 43 | 44 | resp <- httr::POST(url = url, body = req, encode = "json", 45 | httr::add_headers("Authorization" = auth, 46 | "Content-Type" = "application/json")) 47 | resp 48 | } -------------------------------------------------------------------------------- /R/azuremlService.R: -------------------------------------------------------------------------------- 1 | 2 | #' Make a POST request to AzureML service and parse the reponse 3 | #' 4 | #' @param datasets A named list of data frames to send to the web service. 5 | #' The names must match the names of the web inputs in Azure, eg. list(WebInput = data.frame(x=1, y=2)) 6 | #' @param url If you supply the full URL then other options are not required 7 | #' @param region The Azure region, such as ussouthcentral, europewest 8 | #' @param workspace The workspace ID 9 | #' @param service The service ID 10 | #' @param auth Authentication token. Careful not to save this anywhere and 11 | #' check your .Rhistory 12 | #' @param details Logical. If FALSE then column types are omitted from the 13 | #' response 14 | #' 15 | #' @return A list of output data frames. If the service responds with an error code a warnring is printed and the httr::response object is returned 16 | #' @export 17 | #' 18 | #' @examples 19 | #' \dontrun{ 20 | #' azuremlService(list(WebInput = data.frame(x=1:5, y=LETTERS[1:5])), 21 | #' region = "ussouthcentral", 22 | #' workspace = "8550bbba99572fc47e18e5fdd53e43e2", 23 | #' service = "4e7ebd7ad816cd9dd1cb1b17c4cdb0c7", 24 | #' auth = "xxxxxxxxxxxx==") 25 | #' } 26 | azuremlService <- function(datasets, url = NULL, region = "ussouthcentral", 27 | workspace=NULL, service=NULL, auth = NULL, details = TRUE) { 28 | 29 | # Make the request 30 | resp <- makeRequest(datasets = datasets, url = url, region = region, 31 | workspace = workspace, service = service, auth = auth, 32 | details = details) 33 | 34 | # Report errors? 35 | if (resp$status_code != 200) { 36 | respContent <- httr::content(resp) 37 | stpMsg <- paste(c("Request unsuccessful. Status code ", resp$status_code), 38 | jsonlite::toJSON(respContent$error, pretty = TRUE), collapse = "\n") 39 | warning(stpMsg) 40 | return(invisible(resp)) 41 | } 42 | 43 | # Parse the response 44 | parseResponse(resp) 45 | 46 | } 47 | --------------------------------------------------------------------------------