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
R: Assign Variable Labels of Data Frame Columns
Joining Aggregated Values Back to the Original Data Frame
Variable Name Restrictions in R
Identify All Objects of Given Class for Further Processing
Databricks Configure Using Cmd and R
Setting Document Title in Rmarkdown from Parameters
Faster Weighted Sampling Without Replacement
Getting a Stacked Area Plot in R
Ggplot2: Adding Secondary Transformed X-Axis on Top of Plot
Rbind Data Frames Based on a Common Pattern in Data Frame Name
Using Substitute to Get Argument Name
How to Extract the Row with Min or Max Values
How to Define Fixed Aspect-Ratio for (Base R) Scatter-Plot
Formatting Reactive Data.Frames in Shiny
R Knitr: Possible to Programmatically Modify Chunk Labels