Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using chrome_print() inside a Shiny App #91

Closed
ColinFay opened this issue Mar 27, 2019 · 8 comments · Fixed by #97
Closed

Using chrome_print() inside a Shiny App #91

ColinFay opened this issue Mar 27, 2019 · 8 comments · Fixed by #97

Comments

@ColinFay
Copy link

Hey,

I was thinking about implementing a shinyPrint() function that would allow capturing screenshots of current divs of the app.

My first try was:

shinyPrint <- function(
    id, 
    con,
    session = shiny::getDefaultReactiveDomain()
){
    # get the url
    url <- sprintf(
        "%s//%s:%s", 
        session$clientData$url_protocol, 
        session$clientData$url_hostname, 
        session$clientData$url_port
    )
    # screenshot the object
    pagedown::chrome_print(
        url, 
        output = con,  # temp file
        format = tools::file_ext(con), # extension of the temp file
        selector = sprintf("#%s", session$ns(id)) # to be sure to have the correct id
    )
}

On our old friend the Old Faithful Geyser Application :

ui <- fluidPage(
    titlePanel("Old Faithful Geyser Data"),
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins","Number of bins:",1,50,30)
        ),
        mainPanel(
            plotOutput("distPlot"), 
            downloadButton("foo", "foo")
        )
    )
)


server <- function(input, output, session) {
    
    output$distPlot <- renderPlot({
        x    <- faithful[, 2]
        bins <- seq(min(x), max(x), length.out = input$bins + 1)
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
    })
    
    output$foo <- downloadHandler(
        filename = function() {
            paste('data-', Sys.Date(), '.png', sep='')
        },
        content = function(con) {
            shinyPrint(id = "distPlot", con)
        }
    )
}

shinyApp(ui = ui, server = server)

But when I try to run that, I have a blank output:

Screenshot 2019-03-27 at 15 13 07

Running

# Just to be sure it's not related to the fact that it's a tempfile
output = tempfile(fileext = "png")
pagedown::chrome_print(
  "http://127.0.0.1:6745/", 
  output = output,
  format = "png",
  selector = "#distPlot"
)
browseURL(output)

From another R session works, though.

More information (if ever this helps)

If I launch the very same app, but add a Sys.Sleep() of 60 seconds, if I try to do a chrome_print() from another session, it times out.

So my guess is that chrome_print() fails to catch a Shiny app while it's busy.

Not sure if this is an issue you want to dig into. Just, if ever it's easy to fix, a shinyPrint() function wrapping chrome_print() would be nifty.

Colin

@yihui
Copy link
Member

yihui commented Mar 27, 2019

Running chrome_print() inside any later tasks (such as a Shiny app, because shiny uses httpuv, which uses later to run the server) is very likely to be problematic because of this:

later::run_now()

This is the major caveat of chrome_print(). Hopefully r-lib/later#84 will save us.

@ColinFay
Copy link
Author

Ok, so... let's wait :)

RLesur added a commit that referenced this issue Apr 10, 2019
* returns a promise when used in Shiny

* use finally to clean headless chrome session

* add an async argument to chrome_print: this permits to move promises in Suggests and remove shiny dependency
see #97 (review)

* update NEWS

* adapt the styling code

* Update documentation

Explain that async = TRUE requires the promises package

Co-Authored-By: RLesur <RLesur@users.noreply.github.com>

* roxygenize

* do not turn async to FALSE if promises is not installed

Co-Authored-By: RLesur <RLesur@users.noreply.github.com>

* handle exceptions

* factor out reject calls and simplify code using default functions for resolve and rejects
see #97 (comment)

* just return early
see #97 (comment)
@wch
Copy link

wch commented Aug 7, 2019

I can make a PR to use a private event loop so that it's safer -- but the new version of later has not yet been released to CRAN. Do you want a PR now that has a Remotes field? You could hold off merging if you don't want to take a dependency on a package that's only on Github.

@yihui
Copy link
Member

yihui commented Aug 8, 2019

@wch Joe has already submitted a PR #127. Thanks!

@wch
Copy link

wch commented Aug 8, 2019

Ah, I didn't notice that. Great!

@smsenkier
Copy link

So chrome_print still can't be used in a ShinyApp? or is there a fix in the dev version?

@RLesur
Copy link
Collaborator

RLesur commented Nov 25, 2019

I haven't tested so far but with the current CRAN version, pagedown::chrome_print(..., async = TRUE) should work in a Shiny app.

@smsenkier
Copy link

Ok. I was getting some errors when attempting to print a .Rmd file. I needed to install chrome on my remote machine. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants