I am creating an API for a random forest model deployment using the plumber package.
However, I always get the following error, which is probably about data loading:
"error": "405 - Method Not Allowed"
Below, I attached a reproducible example of my code with a simpler model. The error was the same.
library(plumber)
library(tidyverse)
library(jsonlite)
library(plumber)
set.seed(1234)
df <- tibble(x1 = rnorm(10),
x2 = rnorm(10),
epsilon = rnorm(10, mean = 0, sd = 1)) %>%
mutate(y = x1 3*x2 epsilon)%>%
select(y, x1, x2)
lm_model <- caret::train(y ~.,
data = df,
method = "lm")
#* Health Check - Is the API running?
#* @get /health-check
status <- function() {
list(status = "All Good!",
time = Sys.time())
}
#* Log some information about the incoming request
#* @filter logger
function(req){
cat(as.character(Sys.time()), "-",
req$REQUEST_METHOD, req$PATH_INFO, "-",
req$HTTP_USER_AGENT, "@", req$REMOTE_ADDR, "\n")
forward()
}
#> function(req){
#> cat(as.character(Sys.time()), "-",
#> req$REQUEST_METHOD, req$PATH_INFO, "-",
#> req$HTTP_USER_AGENT, "@", req$REMOTE_ADDR, "\n")
#>
#> forward()
#> }
#* Predict y
#* @filter /predict
function(req, res){
if(grepl("predict", req$PATH_INFO)){
req$predict_data <- tryCatch(jsonlite::fromJSON(req$postBody) %>%
as.data.frame(),
error = function(x){
return(NULL)
})
if(is.null(req$predict_data)){
res$status <- 400
return(
list(error = "No JSON file is found in the request")
)
}
req$predicted_values <- predict(lm_model, req$predict_data)
}
forward()
}
#> function(req, res){
#> if(grepl("predict", req$PATH_INFO)){
#> req$predict_data <- tryCatch(jsonlite::fromJSON(req$postBody) %>%
#> as.data.frame(),
#> error = function(x){
#> return(NULL)
#> })
#>
#> if(is.null(req$predict_data)){
#> res$status <- 400
#> return(
#> list(error = "No JSON file is found in the request")
#> )
#> }
#> req$predicted_values <- predict(lm_model, req$predict_data)
#> }
#> forward()
#> }
#* Predict y for given data
#* @post /predict/values
function(req){
y <- as.numeric(req$predicted_values)
return(y)
}
#> function(req){
#> y <- as.numeric(req$predicted_values)
#> return(y)
#>
#> }
I use API via Postman. I send my request in a JSON format and you can find an example below. I try to change formatting, but it did not work. The API works when I do not submit any data. The health check API works as well.
[
{
"x1" : 3,
"x2" : 5
}
]
What can be the problem? How can I solve it?
Thank you very much.
CodePudding user response:
According to Plumber’s changelog, as of Plumber 1.1.0:
[the] experimental option plumber.methodNotAllowed […] (which is enabled by default) allows for a status of 405 to be returned if an invalid method is used when requesting a valid route.
I see that you have just added the @post
method to your /predict/value
endpoint. Most probably you are calling the API with the GET method from Postmann. This would the return the error you specified.
You can fix this by either:
- Calling the API with the POST method from Postman, or
- Adding ‘@get /predict/values` to your predict function.
Hope this solves your problem.