How do I find out whether code is running inside Shiny?

199 views
Skip to first unread message

Konrad Rudolph

unread,
Jun 15, 2015, 9:17:04 AM6/15/15
to shiny-...@googlegroups.com

For my package klmr/modules I need to find out if code is being run from inside Shiny(Apps) or directly in R/via a script. Ultimately, this is necessary in order to find the path of the R source file that is calling the code.

At the moment, I am implementing this check by walking up the call stack to find out whether the code is being called by shiny::runApp. I’m wondering whether this is a good (enough) test, whether it’s robust to future changes, and whether there’s a better way. In particular, for Shiny Server the function serverInfo seems to accomplish what I want but no equivalent seems to exist for running Shiny without Shiny Server.

Code of my current implementation:

shiny_path = function () {
    # Look for `runApp` call somewhere in the call stack.
    frames = sys.frames()
    calls = lapply(sys.calls(), `[[`, 1)
    call_name = function (call)
        if (is.function(call)) '<closure>' else deparse(call)
    call_names = vapply(calls, call_name, character(1))

    target_call = grep('^runApp$', call_names)

    if (length(target_call) == 0)
        return(NULL)

    target_frame = frames[[target_call]]
    namespace_frame = parent.env(target_frame)
    if(isNamespace(namespace_frame) && environmentName(namespace_frame) == 'shiny')
        getwd()
}


Joe Cheng

unread,
Jun 15, 2015, 1:33:33 PM6/15/15
to Konrad Rudolph, shiny-...@googlegroups.com
Nothing else comes to mind.

I can't promise that we will never break this, but it would be surprising.

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/8533cad5-e0bb-43df-8580-67e54f08d9f0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andy Kipp

unread,
Jun 15, 2015, 1:54:31 PM6/15/15
to Joe Cheng, Konrad Rudolph, shiny-discuss
Joe,

Would this method also work for apps running on shinyapps.io?

-Andy

Joe Cheng

unread,
Jun 15, 2015, 1:55:48 PM6/15/15
to Andy Kipp, Konrad Rudolph, shiny-discuss
Yeah, it should be the same.

Konrad Rudolph

unread,
Jun 15, 2015, 2:26:24 PM6/15/15
to shiny-...@googlegroups.com, konrad....@gmail.com, j...@rstudio.com
I can confirm that this method does currently work with shinaypps.io (in fact, that’s what I mostly need it for). At any rate, if Joe doesn’t see an immediate problem with this method I think it’s good enough for my purposes. Thanks!

Dean Attali

unread,
Jun 15, 2015, 6:49:20 PM6/15/15
to shiny-...@googlegroups.com, konrad....@gmail.com
This comment probably won't be too useful, but I just want to get it out there:
From experience, I've noticed it's also possible to run an app by "print"-ing a `shinyApp(...)` function.

For example

  shinyApp(
    ui = fluidPage(
    ),
    server = function(input, output, session) {
      cat(shiny_path())
    }
  )

If you run this code, `runApp` is never used, but the shiny app will get launched. Similarly, if you put this code inside a function as the last statement in a function and then call the function, the shiny app will launch without a `runApp`.  I've never seen any documentation for this behaviour so my guess is that this is just a convenience behaviour that's not meant to be used in production (Joe can maybe comment on whether this is true or not?). So in this case your method will not work if my understanding is correct, but I don't think you should worry about it

Konrad Rudolph

unread,
Jun 16, 2015, 2:45:52 PM6/16/15
to shiny-...@googlegroups.com, konrad....@gmail.com
On Monday, 15 June 2015 23:49:20 UTC+1, Dean Attali wrote:
This comment probably won't be too useful, but I just want to get it out there:
From experience, I've noticed it's also possible to run an app by "print"-ing a `shinyApp(...)` function.
[…]
If you run this code, `runApp` is never used, but the shiny app will get launched. Similarly, if you put this code inside a function as the last statement in a function and then call the function, the shiny app will launch without a `runApp`.  I've never seen any documentation for this behaviour so my guess is that this is just a convenience behaviour that's not meant to be used in production (Joe can maybe comment on whether this is true or not?). So in this case your method will not work if my understanding is correct, but I don't think you should worry about it

Very good point, I forgot about this; it is actually documented behaviour (see e.g. here: http://shiny.rstudio.com/articles/single-file.html). But it so happens that in my particular case this already does the right thing anyway.

Regardless, good job pointing this out.

Joe Cheng

unread,
Jun 16, 2015, 2:49:40 PM6/16/15
to Konrad Rudolph, shiny-...@googlegroups.com
It should still work, as those code paths all lead to runApp() anyway. I don't think there's a way to run a Shiny app without runApp().

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.

Dean Attali

unread,
Jun 16, 2015, 4:04:25 PM6/16/15
to shiny-...@googlegroups.com, konrad....@gmail.com
I know it doesn't matter much, but I tested it out, and it looks like `runApp` is not used when printing a `shinyApp()` call.

The function call stack when using `runApp(shinyApp(...))` is: runApp --> shinyCallingHandlers --> ...

The function call stack when using `shinyApp(...)` is: print --> print.shiny.appobj --> do.call --> <closure> --> shinyCallingHandlers --> ...

Joe Cheng

unread,
Jun 16, 2015, 4:07:38 PM6/16/15
to Dean Attali, shiny-...@googlegroups.com, konrad....@gmail.com

Dean Attali

unread,
Jun 16, 2015, 4:10:33 PM6/16/15
to shiny-...@googlegroups.com, konrad....@gmail.com, daat...@gmail.com
As far as Konrad's method is concerned - no. His method is looking at the function that was called, so in the do.call case it only returns "do.call", so when grepping the stack it doesn't see a `runApp` and will not think that this is shiny code. That's the problem with these hacky solutions :)

Dean Attali

unread,
Aug 18, 2017, 12:28:06 AM8/18/17
to Shiny - Web Framework for R, konrad....@gmail.com, daat...@gmail.com
If anyone ever runs into this thread: this now has a solution built into shiny - the "isRunning()" function
Reply all
Reply to author
Forward
0 new messages