R Shiny REST API 通信

问题描述 投票:0回答:2

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

但是来自 API 的文件名会有所不同。那么有什么方法可以根据来自 API 的 Post 请求使其动态化。

r rest shiny shiny-server
2个回答
11
投票

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


8
投票

到目前为止,在这种情况下需要提到库(plumber)作为替代方案,但是以下示例显示了如何直接在shiny中处理POST请求。

它基于 Joe Cheng 的要点here,建议向 UI 添加属性

"http_methods_supported"
并使用
httpResponse
来应答请求。

下面的代码在后台 R 进程中启动一个闪亮的应用程序(这样做只是为了拥有单个文件 MRE - 当然,您可以将应用程序放在单独的文件中并删除

r_bg
行)。应用程序启动后,父进程将 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()

另请查看此相关 PR,它提供了更多示例(还展示了如何使用

session$registerDataObj
),旨在更好地描述
httpResponse
功能。

© www.soinside.com 2019 - 2024. All rights reserved.