-
Notifications
You must be signed in to change notification settings - Fork 76
Description
Prework
- Read and agree to the code of conduct and contributing guidelines.
- If there is already a relevant issue, whether open or closed, comment on the existing thread instead of posting a new issue.
- New features take time and effort to create, and they take even more effort to maintain. So if the purpose of the feature is to resolve a struggle you are encountering personally, please consider first posting a "trouble" or "other" issue so we can discuss your use case and search for existing solutions first.
- Format your code according to the tidyverse style guide.
Proposal
Let's make it easier to write Shiny apps that run targets
pipelines behind the scenes. This will require some new features and a chapter in the manual.
Parameterized target scripts
A Shiny app with a targets
pipeline should have a central _targets.R
script. This file should live at the root of the app code, and its contents must not change when the app runs. However, the pipeline needs to change based on inputs from the app user: for example, to use a different set of R scripts to populate functions or construct the targets themselves.
To programmatically modify pipelines from the calling R process, we can support parameterized _targets.R
files. The targets
user (app developer) would set/get parameters in the calling process (Shiny session). Then, targets
would substitute them inline into a temporary copy of _targets.R
, and then run that temporary copy. Parameters should be small character strings of length 1. I know some people will want to substitute more text - for example, entire pipeline definitions - but in those cases, it is better to define those targets as external scripts and pass the paths as parameters instead.
### Script helpers
tar_script()
helps write _targets.R
, but apps might need to write other R scripts dynamically. A new tar_helper()
function could assist with this.
Set the path to the data store
Originally, I wanted the data store to always live at _targets/
in the project root. However, that does not bode well for Shiny apps because we cannot write to the local app code. The best current workaround is to wrap every call tar_make()
etc. in withr::with_dir()
, but this leads to uncertainty and inconsistency. In this situation (but not many others) it is better to let the user set the path. This requires a new path_store
option (tar_option_set(path_store = ...)
) which gets forwarded to targets that build on HPC workers (in case the user selects storage/retrieval on workers).
User storage helpers
The tools
package in R >= 4.0 supports a nice R_user_dir()
function for persistent user-specific data, configuration, and cache files. And if we conditionally import it from backports
(with @rawNamespace
) then we can use it in earlier versions of R. Some wrappers would help manage app storage for multiple sessions across multiple users.
tar_user_dir(id = "main")
: short forfile.path(tools::R_user_dir(), id)
, whereid
is a session ID.tar_user_path(path, id = "main")
: short forfile.path(tools::R_user_dir(), id, path)
.tar_user_store_get(id = "main")
: short fortar_user_path("_targets", id = "main")
tar_user_store_set(id = "main")
: short fortar_option_set(path_store = tar_user_store_get(id))
.