Dash: R component generator does not support exporting of arbitrary objects as globals

Created on 29 Apr 2020  路  5Comments  路  Source: plotly/dash

Hello,

I'm trying to add some custom code to dash-bootstrap-components for R, specifically CDN links for different Bootstrap stylesheets. @rpkyle kindly gave me some pointers over on this issue trying to do the same thing for Dash.jl. I added something like this in R/themes.R

dbcThemes <- list(BOOTSTRAP = "https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css")

The idea being that the user can easily link external stylesheets like they would in the Python version by doing something like

app <- Dash$new(external_stylesheets = dbcThemes$BOOTSTRAP)

But it seems that here the code is only looking for functions to add to the exports, which means my list isn't getting picked up.

What would be the best way forward here? I could make a function that acts roughly like a list dbcThemes('BOOTSTRAP'), at the cost of losing autocompletion for discovery of themes and diverging from the interface in the Python version. Alternatively I think it would take some changes in _r_components_generation.py, and I don't have a good sense of how problematic that is. Would it make sense to just export all variables / functions defined in the global scope? Or maybe all variables / functions in global scope not prefixed by some particular sequence of characters (my Python brain was going to suggest _ but I don't think that's valid R...).

Most helpful comment

Hey @rpkyle

Thanks for such a detailed response, I totally understand why you wouldn't want to auto-export all variables detected by the component generator 馃槵

The .onLoad function looks like a nice compromise, I'll definitely check it out!

it is more verbose, but passing the URL via external_stylesheets will work right now.

Can confirm that works well 馃檪

All 5 comments

I added something like this in R/themes.R

dbcThemes <- list(BOOTSTRAP = "https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css")

The idea being that the user can easily link external stylesheets like they would in the Python version by doing something like

app <- Dash$new(external_stylesheets = dbcThemes$BOOTSTRAP)

Hi @tcbegley -- it is more verbose, but passing the URL via external_stylesheets will work right now.

What would be the best way forward here? I could make a function that acts roughly like a list dbcThemes('BOOTSTRAP'), at the cost of losing autocompletion for discovery of themes and diverging from the interface in the Python version.

In terms of a solution which permits the syntax you'd like to use, I'm uncomfortable with modifying the generator to export arbitrary objects (e.g. lists or variables) from within the package to the global environment. Not sure if @Marc-Andre-Rivet has any thoughts here.

I can foresee a few challenges with that approach -- one alternative possibility is to add an .onLoad function to your package, which should run when the package is attached. (.onAttach is related, but intended for interactive use.)

This function is found by loadNamespace without needing to be exported within the NAMESPACE file explicitly (we should probably look for functions which begin with ., and omit them from the list of exported objects in the generator).

The dplyr package does this, for example:

https://github.com/tidyverse/dplyr/blob/bbcfe99e29fe737d456b0d7adc33d3c445a32d9d/R/zzz.r

There might be a more elegant way, but one solution that will likely work for you is to declare .onLoad() with call to assign into the global environment:

.onLoad <- function() {
  dbcThemes=list(BOOTSTRAP = "https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css")
  assign("dbcThemes", dbcThemes, envir=.GlobalEnv)
}

If you're interested, there's a bit more detail here:
https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Load-hooks

In terms of a Julia solution which has the same effect operationally, I'll defer to @waralex 馃檪

Hey @rpkyle

Thanks for such a detailed response, I totally understand why you wouldn't want to auto-export all variables detected by the component generator 馃槵

The .onLoad function looks like a nice compromise, I'll definitely check it out!

it is more verbose, but passing the URL via external_stylesheets will work right now.

Can confirm that works well 馃檪

The .onLoad function looks like a nice compromise, I'll definitely check it out!

Great -- I'll confirm that we ignore those which begin with . when parsing scripts for user-defined functions to add to the NAMESPACE file. If we don't, I'll open a quick PR to do that.

@tcbegley If you feel the suggestion addresses your issue, I'll close this issue once I confirm that the generator behaves as desired.

If you feel the suggestion addresses your issue, I'll close this issue once I confirm that the generator behaves as desired.

Yes by all means feel free to close. Thanks again!

@tcbegley Good news, I think your use case (private unexported functions which begin with .) is covered -- should work as-is for you:

https://github.com/plotly/dash/blob/3f932f691c4e62746507c892fa6c0b4a02f84a34/dash/development/_r_components_generation.py#L799-L803

Closing now, but do let me know how it goes! If you run into a snag, just ping me and we can sort it out.

Was this page helpful?
0 / 5 - 0 ratings