Skip to content

Instantly share code, notes, and snippets.

@gadenbuie
Last active September 8, 2023 00:32
Show Gist options
  • Save gadenbuie/c19cf997467930729ec9acaf98a150fb to your computer and use it in GitHub Desktop.
Save gadenbuie/c19cf997467930729ec9acaf98a150fb to your computer and use it in GitHub Desktop.
library(shiny)
library(jsonlite)
# we'll store received data in a local json file
write_json(list(), "data.json")
post_handler <- function(req, response) {
# we'll catch everything that's POST for this demo but you'll want to make
# sure you don't step on shiny's built-in POST handlers
# (I'm pretty sure this handler is called after shiny's handlers but :shrug:)
if (identical(req$REQUEST_METHOD, "POST")) {
# you probably want to limit the upload file size w/ the first arg of $read()
data <- req$rook.input$read()
data <- jsonlite::fromJSON(rawToChar(data))
message(str(data))
if (is.null(data$token) || is.null(data$name)) {
# expect a token and a name for this demo but you'd want to do auth/routing here...
# if the request is bad return the base response of 404 not found
return(response)
} else {
# update our local data store (or write to db etc)
y <- list()
y[[data$token]] <- data$name
x <- utils::modifyList(read_json("data.json"), y, keep.null = TRUE)
write_json(x, "data.json")
# return all okay response!
return(httpResponse(200, "text/plain", "OK\n"))
}
}
# return regular shiny response
response
}
options(shiny.http.response.filter = post_handler)
ui <- fluidPage(
h2("Hello", uiOutput("name", inline = TRUE, container = span))
)
server <- function(input, output, session) {
# reveal token which we'll use as if it were a user id
message(session$token)
# poll our data store (local json) for updates, using token as ID
name <- reactiveFileReader(1000, session, "data.json", function(x) {
data <- read_json(x)
if (session$token %in% names(data)) {
data[[session$token]]
}
})
output$name <- renderUI({
if (is.null(name())) return("...")
paste0(name(), "!")
})
}
shinyApp(ui, server)
@gadenbuie
Copy link
Author

To test it set token and name in bash and send json via curl:

token=____
name=____
curl -X POST -H "Content-Type: application/json" -d "{\"name\": \"$name\", \"token\": \"$token\"}" http://127.0.0.1:3185

(don't forget to update the url to point to your shiny app)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment