style studio mtext ggplot r shiny shiny-server

studio - Aceptar solicitud HTTP en R aplicación brillante



tags$style shiny (3)

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

Para simular esto, puedo enviar lo siguiente a la aplicación brillante 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 brillante.

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!


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

brillante 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 <img> .
  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( '' <script type="text/javascript"> $(document).ready(function() { // creates a handler for our special message type Shiny.addCustomMessageHandler("api_url", function(message) { // set up the the submit URL of the form $("#form1").attr("action", "/" + message.url); $("#submitbtn").click(function() { $("#form1").submit(); }); }); }) </script> '' ))), tabsetPanel( tabPanel(''POST request example'', # create a raw HTML form HTML('' <form enctype="multipart/form-data" method="post" action="" id="form1"> <span>Name:</span> <input type="text" name="name" /> <br /> <span>Passcode: </span> <br /> <input type="password" name="passcode" /><br /> <span>Avatar:</span> <input name="file" type="file" /> <br /> <input type="button" value="Upload" id="submitbtn" /> </form> '') ) ) ))

Ahora, digamos que ingreso esta 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 a a¨?§i ÕiTXtXML:com.adobe.xmp <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.1.2"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:tiff="http://ns.adobe.com/tiff/1.0/"> <tiff:Compression>5</tiff:Compression> <tiff:PhotometricInterpretation>2</tiff:PhotometricInterpretation> <tiff:Orientation>1</tiff:Orientation> </rdf:Description> </rdf:RDF> </x:xmpmeta> # 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!


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.


Emocionante actualización: A partir de enero de 2017, se anunció en RStudio Conf que esto se incorporará en brillante 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.