R Shiny Rest API Communication

Accept HTTP Request in R shiny application

You can receive GET requests using session$clientData. An example run the following

library(shiny)
runApp(list(
ui = bootstrapPage(
textOutput('text')
),
server = function(input, output, session) {
output$text <- renderText({
query <- parseQueryString(session$clientData$url_search)
paste(names(query), query, sep = "=", collapse=", ")
})
}
), port = 5678, launch.browser = FALSE)

and navigate to

http://127.0.0.1:5678/?transformerData=data/TransformerDataSampleForShiny.json

See @Xin Yin answer for a method to expose POST requests.

Is there a way to request a Shiny app via GET?

This can be done via plumber (httr can be used on the client side).

The following creates plumber API which runs a shiny app in a background R process and returns the according port of the shiny app once the port endpoint is accessed:

library(plumber)
library(shiny)
library(httpuv)
library(callr)

#* @apiTitle Shiny runApp API
#* @apiDescription runs a shiny app and returns the port.

#* Echo back the input
#* @param port The shiny app port
#* @get /port
function() {
ui <- fluidPage(
h1("This is a test app")
)
server <- function(input, output, session) {}
app <- shinyApp(ui, server)
port <- httpuv::randomPort()
r_bg(function(app, port){
shiny::runApp(appDir = app,
port = port,
launch.browser = FALSE,
host = "0.0.0.0")
}, args = list(app = app, port = port), supervise = TRUE)

port
}

# plumb(file='plumber.R')$run()
# http://127.0.0.1:6107/port

Also see my answer here on how to handle http verbs directly with a shiny app.

Is it possible to send data to a shiny app?

Of course you can! An R Shiny app can receive data in the same ways any web app can. E.g. it could run an internal timer to go and fetch data from an API, scrape data from the web, or access a database.

Some suggestions

  • You could simply connect to a remote database (e.g. here's how to connect to a sql server database (it's easier than it looks)
  • You could build an API in whatever language suited you. If you wanted to use R, the plumber package would be a good place to start
  • One unusual way (just to show what's possible) is if you already know how to build a web app, then you could make one that displays the data you want your shiny app to have access to, then have the Shiny app scrape the data at whatever interval you choose (5 seconds, 5 hours, 5 days, anything). Note that this would not be a good solution for any sensitive data

Two of the most used scraping packages are rvest and (Hadley Wickham's) httr. These are a great start for accessing APIs or scraping raw data from anywhere on the web

If you wanted to connect to a database, I recommend deciding which one you'll use then googling how to connect to it using R. Once you've succeeded, you can move that code inside the Shiny app!

Shiny Server reacts to browser URL but not GET from httr

Shiny apps are really designed to communicate with a client via websockets. For handling HTTP requests, you might want to consider a different approach, e.g. a plumber API.

Here's a tailored example of that:

p <- callr::r_bg(
function() {
library(plumber)

pr() |>
pr_handle("GET", "/", function(outFile) {
write("Hello", outFile)
}) |>
pr_run(port = 9850)
}
)

httr::GET("http://127.0.0.1:9850?outFile=hello.txt")
readLines("hello.txt")

p$kill()


Related Topics



Leave a reply



Submit