【问题标题】:R Shiny REST API communicationR Shiny REST API 通信
【发布时间】:2014-10-06 16:04:21
【问题描述】:

我有一个闪亮的应用程序,它采用 Json 中的输入文件通过分类器运行它并返回分类的 Json 对象。 我希望应用程序能够与 API 通信。我希望 API 将文件发布到 Shiny 应用程序,该应用程序将完成其工作并返回分类对象。 基本上,我希望 Shiny 应用程序位于后台,直到发布文件,然后执行其工作。 我知道我可以使用 httr 包中的 GET 从 url 获取文件。如果我知道 get 命令的文件名,我可以把它放在 shiny.server 文件中

但是来自 API 的文件名会有所不同。那么有什么方法可以让我根据来自 API 的 Post 请求进行动态处理。

【问题讨论】:

  • 澄清一下,您是否尝试使用 Shiny 实现 RESTful API:客户端(例如,您的浏览器)将 JSON 格式的输入文件发送给 Shiny,并让 Shiny 将分类对象返回给客户?
  • 嗨,这正是我想要做的
  • 至少有两种方法可以做到这一点。如果您希望通过 AJAX 请求来实现它,您可以查看this example here。或者,您可以使用自定义 input bindingoutput binding
  • 我给你的AJAX例子不是很简单。例如,它没有演示如何在 javascript 中构造 AJAX 请求。相反,它直接将 AJAX URL 绑定到 selectize.js 控件。在 Shiny 中使用 AJAX 请求的更明确的示例可以在 this answer 中找到,尽管还有一些微小的改进空间。
  • 只是在这里链接到一个相关的问题:Accept HTTP Request in R shiny application

标签: r rest shiny shiny-server


【解决方案1】:

如果你不必使用 Shiny,你可以使用 openCPU。 OpenCPU 自动将您的每个 R 包作为 REST 服务提供。我使用 OpenCPU,它工作正常!这是从另一个程序中使用 R 的最简单方法。

【讨论】:

    【解决方案2】:

    这是基于 Joe Cheng 的要点here,建议在 UI 中添加一个属性"http_methods_supported",并使用httpResponse 来回答请求。

    下面的代码在后台 R 进程中启动一个闪亮的应用程序。应用启动后,父进程将 iris data.frame 发送到 UI。

    在 UI 函数中检查req$PATH_INFO(请参阅uiPattern = ".*"),然后将数值列乘以 10 (query_params$factor) 作为 json 字符串返回。

    library(shiny)
    library(jsonlite)
    library(callr)
    library(datasets)
    
    ui <- function(req) {
      # The `req` object is a Rook environment
      # See https://github.com/jeffreyhorner/Rook#the-environment
      if (identical(req$REQUEST_METHOD, "GET")) {
        fluidPage(
          h1("Accepting POST requests from Shiny")
        )
      } else if (identical(req$REQUEST_METHOD, "POST")) {
        # Handle the POST
        query_params <- parseQueryString(req$QUERY_STRING)
        body_bytes <- req$rook.input$read(-1)
        if(req$PATH_INFO == "/iris"){
          postedIris <- jsonlite::fromJSON(rawToChar(body_bytes))
          modifiedIris <- postedIris[sapply(iris, class) == "numeric"]*as.numeric(query_params$factor)
          httpResponse(
            status = 200L,
            content_type = "application/json",
            content = jsonlite::toJSON(modifiedIris, dataframe = "columns")
          )
        } else {
          httpResponse(
            status = 200L,
            content_type = "application/json",
            content = '{"status": "ok"}'
          )
        }
      }
    }
    attr(ui, "http_methods_supported") <- c("GET", "POST")
    
    server <- function(input, output, session) {}
    
    app <- shinyApp(ui, server, uiPattern = ".*")
    # shiny::runApp(app, port = 80, launch.browser = FALSE, host = "0.0.0.0")
    shiny_process <- r_bg(function(x){ shiny::runApp(x, port = 80, launch.browser = FALSE, host = "0.0.0.0") }, args = list(x = app))
    
    library(httr)
    r <- POST(url = "http://127.0.0.1/iris?factor=10", body = iris, encode = "json", verbose())
    recievedIris <- as.data.frame(fromJSON(rawToChar(r$content)))
    print(recievedIris)
    shiny_process$kill()
    

    还请查看此related PR,它提供了更多示例(还展示了如何使用session$registerDataObj),旨在更好地描述httpResponse 函数。

    【讨论】:

      猜你喜欢
      • 2019-12-02
      • 2022-01-22
      • 1970-01-01
      • 2020-07-31
      • 1970-01-01
      • 2022-11-12
      • 2021-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多