Accepter la requête HTTP dans l'application R shiny
j'ai une application brillante que j'ai faite qui a besoin de récupérer ses données d'un autre serveur, c.-à-d. l'autre serveur lorsque l'application brillante est ouverte envoie une requête à l'application brillante pour ouvrir l'application et lui donner les données dont elle a besoin.
Pour simuler cela, je peux vous envoyer les éléments suivants à la R brillant app quand j'ouvre l'application dans firefox:
http://localhost:3838/benchmark-module/?transformerData=data/TransformerDataSampleForShiny.json
C'est une simple requête get qui envoie la piqûre appelé : "Données Du Transformateur" avec contenu "data / Transformerdataéchantillonforshing.json" à la brillante application.
Lorsque j'utilise le code, il fonctionne très bien:
#(Abridged code, I am only showing the start of the code)
shinyServer(function(input, output) {
jsonFile <- "data/TransformerDataSampleForShiny.json"
JSONdata <- fromJSON(jsonFile)
mais quand je veux faire exactement la même chose sauf que plutôt que le codage dur la chaîne "data/Transformerdataasampleforshiny.json" je veux recevoir cette chaîne de la requête http au-dessus. Comment dois-je faire?? J'ai essayé le code:
shinyServer(function(input, output) {
jsonFile <- input$transformerData
JSONdata <- fromJSON(jsonFile)
et j'ai aussi essayé:
....
jsonFile <- input$TransformerData
mais rien de tout cela n'a fonctionné.
DONC la question principale est: Comment puis-je coder pour recevoir des requêtes HTTP? Je voudrais recevoir des chaînes de caractères à partir de requêtes HTTP GET et / ou de fichiers JSON à partir de requêtes POST.
juste pour clarifier que je ne veux pas envoyer de courrier ou recevoir des demandes de R. Je veux les recevoir. Je ne peux pas utiliser le paquet httr ou le paquet httpRequest pour recevoir
Merci beaucoup!
3 réponses
vous pouvez recevoir des requêtes GET en utilisant session$clientData
. Un exemple exécute ce qui suit
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)
et naviguez vers
http://127.0.0.1:5678/?transformerData=data/TransformerDataSampleForShiny.json
voir la réponse de @Xin Yin pour une méthode pour exposer les requêtes POST.
la réponse de@jdharrison est une façon de gérer GET
demandes dans Brillant.
Malheureusement, sa déclaration
shiny ne traite pas les demandes de courrier malheureusement.
n'est pas, à proprement parler, 100% exact.
Vous poignée POST
demandes de Shiny avec l'aide de la fonction session$registerDataObj
. Un exemple d'utilisation de cette fonction peut être trouvé dans cet exemple,. Au fond, par appel de registerDataObj
fonction, elle renvoie un unique demande de l'URL à laquelle vous pouvez lancer GET
ou POST
demandes. Toutefois, l'exemple ci-dessus ne me semble pas très utile dans le contexte de votre question parce que:
- il n'y a pas d'utilisation explicite D'AJAX dans cet exemple. Plutôt, l'exemple exploite
registerDataObj
pour créer un gestionnaire de fichiers PNG, et il lie directement L'URL ausrc
<img>
balise. - Il est encore à l'aide de
GET
demandePOST
.
mais, vous pouvez Multiplexer cette fonction pratique pour gérer les deux GET
et POST
parfaitement bien.
Considérons l'exemple suivant:
le serveur.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))
})
interface utilisateur.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>
')
)
)
))
maintenant, disons que j'entre ces entrées de test:
Puis appuyez sur "Upload"
, vous soumettez une requête POST au serveur brillant, qui, basé sur notre code R, supprimera le POST de votre navigateur demande de flux pour vous en tant que réponse.
Par exemple, j'obtiens:
------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--
il est clair que vous pouvez gérer non seulement les données textuelles, mais aussi les téléchargements de fichiers aussi longtemps que vous écrivez un processeur de requête POST de manière appropriée. Bien que cela ne soit pas insignifiant, mais au moins c'est plausible et totalement faisable!
bien sûr, vous avez l'inconvénient évident que d'une certaine façon vous avez besoin de communiquer cette unique demander L'URL au client, ou au serveur qui lancer la requête. Mais techniquement, il y a plusieurs façons de le faire!
Excitant de mise à jour: à partir de janvier 2017, il a été annoncé sur RStudio Conf que ceci sera intégré dans shiny dans une version future (commencez à regarder à la minute 15:00).
depuis mai 2017, cette fonctionnalité de L'API n'est toujours pas disponible, mais j'espère qu'elle viendra bientôt.