Aceptar solicitud HTTP en R aplicación shiny

Tengo una aplicación shiny que he hecho que necesita obtener sus datos de otro servidor, es decir, el otro servidor cuando se abre la shiny aplicación envía una solicitud a la shiny aplicación para abrir la aplicación y darle los datos que necesita.

Para simular esto, puedo enviar lo siguiente a la aplicación shiny R cuando abro la aplicación en firefox:

http://localhost:3838/benchmark-module/?transformerData=data/TransformerDataSampleForShiny.json 

Esta es una solicitud de obtención simple que envía la picadura llamada: “Datos del transformador” con el contenido “data / TransformerDataSampleForShing.json” a la aplicación shiny.

Cuando uso el código, funciona bien:

 #(Abridged code, I am only showing the start of the code) shinyServer(function(input, output) { jsonFile <- "data/TransformerDataSampleForShiny.json" JSONdata <- fromJSON(jsonFile) 

pero cuando quiero hacer exactamente lo mismo, salvo que sea difícil codificar la cadena “data / TransformerDataSampleForShiny.json”, quiero recibir esa cadena de la solicitud http anterior. ¿¿Cómo hago esto?? He intentado el código:

 shinyServer(function(input, output) { jsonFile <- input$transformerData JSONdata <- fromJSON(jsonFile) 

y también he intentado:

 .... jsonFile <- input$TransformerData 

pero ninguno de estos ha funcionado.

ASÍ QUE la pregunta principal es, ¿cómo codigo para recibir solicitudes HTTP? Me gustaría recibir cadenas de solicitudes HTTP GET y / o archivos JSON de solicitudes POST.

Solo para aclarar que NO deseo enviar publicaciones u obtener solicitudes de R. Quiero recibirlas. No puedo usar el paquete httr o el paquete httpRequest para recibir

¡Muchas gracias!

Puede recibir solicitudes GET usando la session$clientData . Un ejemplo ejecuta el siguiente

 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) 

y navega a

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

Consulte @Xin Yin answer para conocer un método para exponer las solicitudes POST.

La respuesta de @ jdharrison es una forma de cómo puedes manejar las solicitudes GET en Shiny. Lamentablemente, su statement de que

shiny no maneja las solicitudes POST desafortunadamente.

no es, estrictamente hablando, 100% exacto.

Puede manejar solicitudes POST en Shiny con la ayuda de la session$registerDataObj función session$registerDataObj . Un ejemplo del uso de esta función se puede encontrar en este ejemplo . Básicamente, al llamar a la función registerDataObj , devuelve una URL de solicitud única a la que puede iniciar solicitudes GET o POST . Sin embargo, no consideraría el ejemplo anterior muy útil en el contexto de su pregunta porque:

  1. No hay un uso explícito de AJAX en este ejemplo. Más bien, el ejemplo explota registerDataObj para crear un manejador de archivos PNG y vincula directamente el URL a la propiedad src de la etiqueta .
  2. Todavía está utilizando la solicitud GET no POST .

Pero, puede multiplexar esta práctica función para manejar tanto GET como POST perfectamente bien. Considere el siguiente ejemplo:

servidor.R

 library(shiny) shinyServer(function(input, output, session) { api_url <- session$registerDataObj( name = 'api', # an arbitrary but unique name for the data object data = list(), # you can bind some data here, which is the data argument for the # filter function below. filter = function(data, req) { print(ls(req)) # you can inspect what variables are encapsulated in this req # environment if (req$REQUEST_METHOD == "GET") { # handle GET requests query <- parseQueryString(req$QUERY_STRING) # say: # name <- query$name # etc... } if (req$REQUEST_METHOD == "POST") { # handle POST requests here reqInput <- req$rook.input # read a chuck of size 2^16 bytes, should suffice for our test buf <- reqInput$read(2^16) # simply dump the HTTP request (input) stream back to client shiny:::httpResponse( 200, 'text/plain', buf ) } } ) # because the API entry is UNIQUE, we need to send it to the client # we can create a custom pipeline to convey this message session$sendCustomMessage("api_url", list(url=api_url)) }) 

ui.R

 library(shiny) shinyUI(fluidPage( singleton(tags$head(HTML( '  ' ))), tabsetPanel( tabPanel('POST request example', # create a raw HTML form HTML(' 
Name:
Passcode:

Avatar:
') ) ) ))

Ahora, digamos que ingreso esta entrada de prueba:

Alguna entrada de prueba

Luego presiona "Upload" , envías una solicitud POST al servidor Shiny, que, en función de nuestro código R, arrojará la transmisión de solicitud POST de tu navegador como respuesta.

Por ejemplo, obtengo:

 ------WebKitFormBoundary5Z0hAYXQXBHPTLHs Content-Disposition: form-data; name="name" foo ------WebKitFormBoundary5Z0hAYXQXBHPTLHs Content-Disposition: form-data; name="passcode" bar ------WebKitFormBoundary5Z0hAYXQXBHPTLHs Content-Disposition: form-data; name="file"; filename="conductor.png" Content-Type: image/png ‰PNG IHDR X ¦ 5Š_ pHYs aa¨?§i ÕiTXtXML:com.adobe.xmp    5 2 1    # here I removed the binary file content ------WebKitFormBoundary5Z0hAYXQXBHPTLHs-- 

Es evidente que puede manejar no solo los datos de texto, sino también las cargas de archivos siempre que escriba un procesador de solicitud POST de forma adecuada. Aunque esto puede no ser trivial, ¡pero al menos es plausible y totalmente factible!

Por supuesto, tiene el inconveniente obvio de que de alguna manera necesita comunicar esta URL de solicitud única al cliente o al servidor que iniciará la solicitud. ¡Pero técnicamente hay muchas maneras en que puedes hacer eso!

Emocionante actualización: A partir de enero de 2017, se anunció en RStudio Conf que esto se incorporará en shiny en una versión futura (comience a ver en el minuto 15:00).

A partir de mayo de 2017, esta función API aún no se ha publicado, pero espero que llegue pronto.