Convert a binary POST request to a local raster

Hi there,
I would like to create a raster from a POST request in plumber API.

After making a POST request with a given raster in body and this POST request reported a status_code = 200. I would like to re-create the raster in the content of the POST request, but I am finding many problems in doing so.

Is there anyone who has experience with this who can help me?

This is the r code that allow to build up the endpoint of the API

#* @param raster:binary
#* @post /prediction
#* @serializer tiff
function(raster){

  filename <- names(raster)
  content <- raster[[1]]
  file <- tempfile(fileext = filename)
  on.exit(unlink(file), add = TRUE)
  writeBin(content, file)

  r <- raster::raster(file)

  print(r)

  return(r)

}

while the following is the code that i am using to make the POST request and the functions that i am using to rebuild the raster passed to the POST request

library(httr)

api_url <- "http://localhost:4867/prediction"

r <- httr::POST(
  api_url,
  body=list(raster=upload_file(".../red_raster.tif"))
)

httr::status_code(r)

bin_raster<-readBin(r$content, what = "raw", n=length(r$content))

writeBin(bin_raster, con = "raster.tif")

r <- raster::raster("raster.tif")

mapview::mapview(r)

Also using this code the reconstructed raster does not have a crs

Quick glance, I would change the extension

file <- tempfile(fileext = paste0(".", tools::file_ext(filename)))

And I would use httr::content to read raw from response.

1 Like

Thanks again for the suggestions @meztez .

I have changed the rcode of the POST request as the following:

#* @param raster:binary
#* @post /prediction
#* @serializer tiff
function(raster){

  filename <- names(raster)
  content <- raster[[1]]
  file <- tempfile(fileext = paste0(".", tools::file_ext(filename)))
  on.exit(unlink(file), add = TRUE)
  writeBin(content, file)

  r <- raster::raster(file)

  print(r)

  return(r)

}

and when i am doing the POST request i am using the following code

library(httr)

api_url <- "http://localhost:8000/prediction"

r <-POST(
  api_url,  body=list(raster=upload_file(".../red.tif"))
)

status_code(r)

bin_raster<-readBin(r$content, what = "raw", n=length(r$content))

writeBin(bin_raster, con = "raster.tif")

r <- raster::raster("raster.tif")

and when i am using the function that you have suggested

httr::content(r, as="raw", type = "image/tiff", encoding="UTF-8")

I have the following output

but still i can't reproduce the raster that i have send with the POST request

You are using an image serializer, you might want to use a plot output? Do you want to return a plot representing the content of the original tiff file OR the original tiff file content. The first one would be the a saved plot in tiff format, the second would the actual tiff source.

raster::plot(r)

Instead of return(r)

Otherwise, you would use an octet serializer, probably with as_attachment

See

library(raster)

#* @param raster:binary
#* @post /prediction
#* @serializer tiff
function(raster){
  
  filename <- names(raster)
  content <- raster[[1]]
  file <- tempfile(fileext = paste0(".", tools::file_ext(filename)))
  on.exit(unlink(file), add = TRUE)
  writeBin(content, file)

  r <- raster::raster(file)
  
  raster::plot(r)

}

#* @param raster:binary
#* @post /prediction2
#* @serializer octet
function(raster){
  
  fn <- names(raster)
  content <- raster[[1]]
  
  plumber::as_attachment(content, fn)

}
1 Like

Thank you for the very comprehensive suggestion.

In fact I had a desire to both create a plot and provide the raw raster data and all the two codes you provided work great.

Thank you very much, a thousand likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.