shiny-server. Print JSON as a result output
Asked Answered
H

5

8

I'm trying to use shiny-server as a process server: receive URL request, process R subroutines and output JSON as a result. but I have been unable print the output directly to the browser in JSON.

Is posible to use shiny-server in this way?

PD: I know that this is not a tipical use for shiny server

Thanks a lot!

Hydrosome answered 15/11, 2013 at 1:7 Comment(4)
Alex, did you ever find a good solution for being able to call R code from a JSON enabled web service?Bellina
Hi @Andrew, my final aproach to solve this problem, was to process the request using Apache2+PHP, and from PHP call my R scripts using shell_exec(). These R scripts accept the inputs in a JSON file and return data in the same way. Shiny-server was not helpful in this case.Hydrosome
thanks for that. I'm assuming though with that approach that you had to incur the 2-3 sec startup time for the R runtime for each and every PHP call.Bellina
call R on our server is faster. We also have implemented a cache for requests that makes everything go fasterHydrosome
A
7

It sounds like you are trying to build a REST or JSON-RPC web service using shiny server. This is not currently possible (with Shiny Server v1.2).

Shiny server renders a text/html template (shinyUI) page and uses WebSocket callbacks to populate the content. The answer from @ScottChamberlain will render the JSON in the HTML body of a web browser. This won't work for a programmatic web request.

I found rApache, Rook and RJSONIO to be a robust and performant solution for JSON web services. You will need to be comfortable with configuring the Apache web server and, depending on your platform, building Apache modules.

rApache is a module that embeds R into the Apache web server allowing you to host Rook, brew and other R frameworks.

Rook defines an interface between R application and a web server. This makes it easy to deliver your JSON payload with the right content-type.

Other options include:

  • OpenCPU - A dedicated R HTTP server with explicit support for JSON RPC
  • node-rio - node.js server that interfaces RServe
  • FastRWeb - CGI or PHP interface to connect a web server to RServe
  • RServe - Binary R TCP/IP server
  • httpuv - HTTP and WebSocket server library for R
  • R's built in rhttpd - not recommended for production use
Addlebrained answered 15/11, 2013 at 1:7 Comment(1)
great answer. To your list of option, I would add RServe and httpuv. Though, they are both low-level, they can be easily used to solve the stated problemThirty
P
8

I found this other package today that wraps R functions RPC/REST-ish:

https://github.com/trestletech/plumber

By commenting an R function like so:

#' @get /mean
normalMean <- function(samples=10){
  data <- rnorm(samples)
  mean(data)
}

#' @post /sum
addTwo <- function(a, b){
  as.numeric(a) + as.numeric(b)
}

You can expose it as a web api:

> library(plumber)
> r <- plumb("myfile.R")  # Where 'myfile.R' is the location of the file shown above
> r$run(port=8000)
Pompea answered 16/7, 2015 at 12:54 Comment(0)
A
7

It sounds like you are trying to build a REST or JSON-RPC web service using shiny server. This is not currently possible (with Shiny Server v1.2).

Shiny server renders a text/html template (shinyUI) page and uses WebSocket callbacks to populate the content. The answer from @ScottChamberlain will render the JSON in the HTML body of a web browser. This won't work for a programmatic web request.

I found rApache, Rook and RJSONIO to be a robust and performant solution for JSON web services. You will need to be comfortable with configuring the Apache web server and, depending on your platform, building Apache modules.

rApache is a module that embeds R into the Apache web server allowing you to host Rook, brew and other R frameworks.

Rook defines an interface between R application and a web server. This makes it easy to deliver your JSON payload with the right content-type.

Other options include:

  • OpenCPU - A dedicated R HTTP server with explicit support for JSON RPC
  • node-rio - node.js server that interfaces RServe
  • FastRWeb - CGI or PHP interface to connect a web server to RServe
  • RServe - Binary R TCP/IP server
  • httpuv - HTTP and WebSocket server library for R
  • R's built in rhttpd - not recommended for production use
Addlebrained answered 15/11, 2013 at 1:7 Comment(1)
great answer. To your list of option, I would add RServe and httpuv. Though, they are both low-level, they can be easily used to solve the stated problemThirty
O
1

What about this simple solution?

https://gist.github.com/sckott/7478126

server.r

require(shiny)
require(RJSONIO)

shinyServer(function(input, output) {
  output$jsonoutput <- renderText({
    toJSON(list(a = 10, b = 12))
  })
})

ui.r

require(shiny)

shinyUI(bootstrapPage(
  mainPanel(
   textOutput(outputId="jsonoutput")
  )
))

The text doesn't print pretty, but...

Also, have a look at this answer on the Shiny mailing list: https://groups.google.com/forum/#!searchin/shiny-discuss/json$20output/shiny-discuss/-JYOXAeLCtI/kslvMve_FmIJ - that Shiny isn't really designed to serve data as an API.

Offensive answered 15/11, 2013 at 2:25 Comment(4)
Hi Scott, I had tried something like that, but does not work well when you make a request from another program (ie PHP), the shiny's javascript code does not run and the page appears without content.Hydrosome
This doesn't return raw JSON. It returns a Shiny HTML page which loads the output. In a web browser, it is cosmetically the same, but it won't work for programatic use as a RESTful webservice.Addlebrained
@Addlebrained Yep, I know that. And I did mention that in my answer.Offensive
@AlexA. If you want a REST service built on R, try OpenCPU opencpu.orgOffensive
E
1

What about hacking shiny.

httpHandler = function(req){
 message = list(value="hello")
 return(list(status = 200L,
             headers = list('Content-Type' = 'application/json'),
             body = toJSON(message)))
}
shiny:::handlerManager$addHandler(shiny:::routeHandler("/myEndPoint",httpHandler) , "a_unique_id")

# then start your shiny app ...

Then point you browser to http://127.0.0.1:[shinyport]/myEndPoint/

Esqueda answered 10/12, 2015 at 10:2 Comment(0)
G
1

For me it worked by using verbatimTextOutput:

ui.R

verbatimTextOutput(outputId="jsonoutput")

server.R - assume the data to be converted into json is returned by getMainData()

output$jsonoutput <- renderText({

data <- getMainData()


result <- jsonlite::prettify(jsonlite::toJSON(data, auto_unbox = TRUE), 4)

return(result)
})
Gravure answered 8/12, 2016 at 16:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.