Accept Http Request in R Shiny Application

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.

R shiny - How send a request url with params to R shiny and get just the data response?

I don't believe you can do that using just Shiny. There are, however, some options to have R behave like an API and return JSON responses. See: http://plumber.trestletech.com/

Return HTTP status codes in R Shiny application

I would suggest using shinyjs to start the session with all UI hidden, and then show the UI only if an authorized user makes the connection.

For example, the following app only show UI to logged-in users. I'm substituting the authorization status with radio buttons to simplify the example, but the logic is the same.

# ui.R

fluidPage(
useShinyjs(),
h1("User Authentication Example"),
radioButtons("login", "Login:", c("Logged out", "Logged in")),
div(id = "logged.in.ui",
p("You are logged in")
) %>% shinyjs::hidden()
)

# server.R

library(shinyjs)

function(input, output) {

# Showing/hiding UI depending on login status.
observeEvent(input$login, {
if (input$login == "Logged in") {
shinyjs::show("logged.in.ui")
} else {
shinyjs::hide("logged.in.ui")
}
})

}

Note the %>% shinyjs::hidden in the UI portion of the above app. This functions to hide all UI within the logged.in.ui div using JavaScript when the session is created and before the login status is checked in the server. Toggling the radio buttons is observed in the server, and the UI content of the logged.in.ui div is shown or hidden depending on the login status.

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