闪亮的 downloadButton() 和 downloadHandler() 500 错误

Shiny downloadButton() and downloadHandler() 500 Error

我开发了一个 Shiny Dashboard,我有几个通过反应式文件阅读器导入的数据框等。我还添加了一个 "Generate PDF" 按钮,在我的 [=34= 中使用 downloadButton() ] 代码。我的 server.R 代码实现了 downloadHandler() 来处理该请求。

在我的 Windows 桌面上,这一切都完美无缺。我希望在我设置的 Linux 服务器上 运行。当然,我必须修改一些路径,并将 Shiny Server 运行s 设置为根目录。当我在 Linux 服务器上的站点 运行ning 上单击 "Generate PDF" 按钮时,我几乎立即收到 HTTP 500 错误。我自己在 Linux 服务器上手动编译了 pdfReport.Rmd 文件,它 运行 很好。

我猜是以下两件事之一:

  1. 数据在 Linux 框上的传递方式与在 Windows 桌面上的传递方式不同。这可能不太可能,但有可能。
  2. 我的路径有问题,所以当写入临时文件以开始生成 PDF 时,系统没有能力或路径不存在来写入文件。可能是我的 downloadHandler() 代码在某种程度上存在格式错误。我认为这比#1 的可能性更高。

这是我的 downloadHandler() 代码:

output$pdfReport <- downloadHandler(
  # For PDF output, change this to "report.pdf"
  filename = reactive({paste0("/srv/shiny-server/itpod/","ITPOD-",Sys.Date(),".pdf")}),

  content = function(file) {
    # Copy the report file to a temporary directory before processing it, in
    # case we don't have write permissions to the current working dir (which
    # can happen when deployed).

    tempReport <- file.path("/srv/shiny-server/itpod", "pdfReport.Rmd")
    file.copy("report.Rmd", tempReport, overwrite = TRUE)

    params <- list(ilp=updateILP(), ico=updateICO(), sec=updateSecurity(), ppwc=updateWorkPreviousPeriodCompleted(),
                   pow=updateOngoingWorkCABApproved(), pwcr=updatePlannedWorkCABRequested(), epca=updateEmergencyChangesPendingCABApproval(),
                   fac=updateFacilities(), drs=updateDRStatus(), ov=updateOperationalEvents(), sl=updateStaffLocations(),
                   w = updateWeather())

    # Knit the document, passing in the `params` list, and eval it in a
    # child of the global environment (this isolates the code in the document
    # from the code in this app).
    rmarkdown::render(tempReport, output_file = file, params = params, envir = new.env(parent = globalenv())
    )
  }
)

我想也许路径是不可写的,所以我尝试将其更改为 /tmp,但这也不起作用。四处寻找,我发现当我点击 "Generate PDF" 按钮时,我得到一个长 URL 和 "session":

http://my.url.com:3838/itpod/session/d661a858f5679aba26692bc9b4442872/download/pdfReport?w=

我开始怀疑这是不是问题所在,我不是在写入当前会话的路径还是什么?这对我来说是 Shiny 的一个新领域。就像我说的,在我的桌面上它工作正常,但是一旦我将它部署到 Linux 服务器,它就无法正常工作。任何帮助将非常感激。提前致谢!

好的 - 经过大量故障排除后,我发现我在闪亮的 webroot 中拥有的一些文件是主 pdfReport.Rmd 文件的依赖项,因为代码将报告复制到临时目录。

因为我不想将所有文件从我的 webroot 复制到临时文件,所以我决定在 webroot 本身内呈现报告。对我来说,这没什么大不了的,因为无论如何我的闪亮应用程序都是 运行 root 用户。

现在我会解决这个问题,基本上我的解决方法是执行以下操作:

  1. 使服务运行成为普通用户
  2. 我将不得不在报告代码中静态引用它们,而不是复制报告所依赖的文件。

对于所有可能已经阅读并正在为此努力的人,我深表歉意。我对上面代码的修复如下:

output$pdfReport <- downloadHandler(
      # For PDF output, change this to "report.pdf"
      filename = reactive({paste0("/srv/shiny-server/itpod/","ITPOD-",Sys.Date(),".pdf")}),

      content = function(file) {
        # Copy the report file to a temporary directory before processing it, in
        # case we don't have write permissions to the current working dir (which
        # can happen when deployed).

        report <- file.path(getwd(), "pdfReport.Rmd")
        #tempReport <- file.path(tempdir(), "pdfReport.Rmd")
        #file.copy("pdfReport.Rmd", tempReport, overwrite = TRUE)

        params <- list(ilp=updateILP(), ico=updateICO(), sec=updateSecurity(), ppwc=updateWorkPreviousPeriodCompleted(),
                       pow=updateOngoingWorkCABApproved(), pwcr=updatePlannedWorkCABRequested(), epca=updateEmergencyChangesPendingCABApproval(),
                       fac=updateFacilities(), drs=updateDRStatus(), ov=updateOperationalEvents(), sl=updateStaffLocations(),
                       w = updateWeather())

        # Knit the document, passing in the `params` list, and eval it in a
        # child of the global environment (this isolates the code in the document
        # from the code in this app).
        rmarkdown::render(report, output_file = file, params = params, envir = new.env(parent = globalenv())
        )
      }
    )

  })

注意,我没有将文件复制到临时目录,而是在当前工作目录中指定文件。