Reputation: 31
I have been developing a REST API using the plumber package. I am still learning the basics of how to do this. I would like the API to:
1) Received POSTed data and parameters and run a model. 2) Send back the results. 3) Print a plot on the web page (or any web page).
I have #1 and #2 working, but I am not finding a way to do #3. I am sure there are some concepts I am not fully understanding.
Here is my script running the API. I have been running this in one instance of RStudio:
# Packages
library(plumber)
library(jsonlite)
#* @post /predict_mtcars
mtcars.driver <- function(df, depVar, predVars){
# Convert objects to JSON
depVar <- fromJSON(depVar)
predVars <- fromJSON(predVars)
df <- fromJSON(df)
df <- df[, c(depVar, predVars)]
fit <- lm(df)
outDf <- data.frame(depVar = df[depVar], 'Predicted' = predict(fit),
'Residuals' = fit$residuals)
print(plot(outDf))
return(toJSON(outDf))
}
Here is my code driving that script:
# Deploy.R
library(plumber)
setwd('YOUR PATH')
r <- plumb("Driver.R")
r$run(port=8080)
And here is a test script that I run on a second instance of RStudio:
# Packages
library(sp)
library(jsonlite)
library(httr)
# Data
data(mtcars)
# Parameters
depVar <- 'mpg'
predVars <- c('cyl', 'hp', 'wt')
df <- mtcars
body <- list("df" = toJSON(df),
"depVar" = toJSON(depVar),
"predVars" = toJSON(predVars))
req <- POST('http://localhost:8080/predict_mtcars',
body = body,
encode = 'json',
verbose())
outDf <- fromJSON(content(req)[[1]][1])
plot(outDf)
All of this works except the print/plot statement in the first script. I have seen very little of this described online but it seems useful to be able to POST data to an API and then have it print plots and other information on the API's website.
Note that I still have a lot to learn about hosting APIs using plumber, so that may be part of the problem. Thanks in advance.
Upvotes: 3
Views: 947
Reputation: 3794
You are almost there! But you are missing a serializer to tell plumber to output your plot as, for example a png. Look at the second line below, where I add @png
. That is the serializer, and is one of many described in the documentation.
#* @post /predict_mtcars
#* @png
mtcars.driver <- function(df, depVar, predVars){
# Convert objects to JSON
depVar <- fromJSON(depVar)
predVars <- fromJSON(predVars)
df <- fromJSON(df)
df <- df[, c(depVar, predVars)]
fit <- lm(df)
outDf <- data.frame(depVar = df[depVar], 'Predicted' = predict(fit),
'Residuals' = fit$residuals)
plot(outDf)
}
When you call a for a plot in png with an API client like insomnia, it will render right there. But with your test script, you will need to get the binary content out of your req
object.
One way to do this would be as follows:
writeBin(req$content, con = file("~/Desktop/outDf.png", "wb"))
This will save your plot as a PNG on your desktop (if you are on Windows, or a Mac you may need to change the path to something sensible for your system.
Upvotes: 1