Skip to content

Dash for R v0.3.0 #175

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

Merged
merged 45 commits into from
Feb 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5c83f5c
Use dev_tools_prune_errors instead of pruned_errors (#113)
rpkyle Aug 23, 2019
d20daa8
Provide support for multiple outputs (#119)
rpkyle Sep 3, 2019
0845184
prepend multiple
Sep 3, 2019
29a3042
Better handling for user-defined error conditions in debug mode (#116)
rpkyle Sep 6, 2019
bbfc6cc
Sep 18, 2019
2e09789
Implement support for clientside callbacks in Dash for R (#130)
rpkyle Oct 1, 2019
c947c73
Provide support for hot reloading in Dash for R (#127)
rpkyle Nov 1, 2019
8e3c168
update percy settings
Nov 4, 2019
5d485d9
Merge pull request #138 from plotly/percy
byronz Nov 4, 2019
5c2ea67
add always
Nov 4, 2019
cd33eba
Merge pull request #139 from plotly/percy
byronz Nov 4, 2019
f866d38
Support for meta tags in Dash for R (#142)
rpkyle Nov 5, 2019
7e16f8d
restore port default
Nov 14, 2019
4b99c88
update codeowners
Nov 29, 2019
2ca3f98
Create CODEOWNERS
Marc-Andre-Rivet Nov 29, 2019
68be6a9
Fixes for hot reloading interval handling and refreshing apps within …
rpkyle Dec 4, 2019
1d5ee2d
Update CHANGELOG.md
rpkyle Dec 4, 2019
e852995
Support for asynchronous loading/compression in Dash for R (#157)
rpkyle Dec 22, 2019
22227f6
make more idiomatic for routr
Dec 22, 2019
006b6d3
:necktie: :hocho: whitespace
Dec 22, 2019
93345e6
Update dash-renderer to 1.2.2 and fix dev tools UI display of stack t…
rpkyle Dec 25, 2019
e6c460a
use versions from dev branch for #996
Dec 25, 2019
8c9678b
Update CHANGELOG.md
rpkyle Dec 25, 2019
61e6dfa
Support returning asset URLs via public method within Dash class (#160)
rpkyle Jan 3, 2020
ca6613c
Update CHANGELOG.md
rpkyle Jan 3, 2020
fb05d18
Minor fix for get_asset_url + docs, add url_base_pathname (#161)
rpkyle Jan 3, 2020
85828d3
Merge branch 'master' into dev
rpkyle Jan 3, 2020
e4cedb3
Autoset routes and requests pathname prefixes (#165)
rpkyle Jan 14, 2020
cc9e06d
Inspect environment variables for host & port (#167)
rpkyle Jan 14, 2020
3733ead
Support for index page templating (#168)
HammadTheOne Feb 11, 2020
2f1be58
Add support for config-aware relative paths (#172)
HammadTheOne Feb 12, 2020
6eddf98
Update CHANGELOG.md
rpkyle Feb 12, 2020
a2907ba
Update DESCRIPTION
rpkyle Feb 12, 2020
98254a1
update authors
Feb 12, 2020
402969d
Merge branch 'dev' of github.com:plotly/dashR into dev
Feb 12, 2020
d7dcae7
Merge branch 'master' into dev
rpkyle Feb 12, 2020
c03c6c1
added dashTable version bump
rpkyle Feb 12, 2020
030adb4
renamed "Removed" section to "Deprecated"
rpkyle Feb 12, 2020
744b696
host & port changes :truck: "Deprecated" section
rpkyle Feb 12, 2020
c853cbf
:see_no_evil: fix typo
rpkyle Feb 12, 2020
7c26675
:see_no_evil: fix typo
rpkyle Feb 12, 2020
49c97da
:see_no_evil: fix typos
Feb 12, 2020
21e78db
Merge branch 'dev' of github.com:plotly/dashR into dev
Feb 12, 2020
2c46d9f
Add unit tests for index customization (#176)
rpkyle Feb 13, 2020
0085036
Send status code of 1 when unit tests fail (#177)
rpkyle Feb 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
. venv/bin/activate
pip install -e git+https://github.com/plotly/dash.git#egg=dash[testing]
export PATH=$PATH:/home/circleci/.local/bin/
pytest --log-cli-level DEBUG --nopercyfinalize --junitxml=test-reports/dashr.xml tests/integration/
pytest --nopercyfinalize --junitxml=test-reports/dashr.xml tests/integration/
- store_artifacts:
path: test-reports
- store_test_results:
Expand All @@ -55,7 +55,7 @@ jobs:
- run:
name: 🔎 Unit tests
command: |
sudo Rscript -e 'testthat::test_dir("tests/")'
sudo Rscript -e 'res=devtools::test("tests/", reporter=default_reporter());df=as.data.frame(res);if(sum(df$failed) > 0 || any(df$error)) {q(status=1)}'

workflows:
version: 2
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
# Change Log for Dash for R
All notable changes to this project will be documented in this file.


## [0.3.0] - 2020-02-12
### Added
- Support for config-aware relative paths [#172](https://github.com/plotly/dashR/pull/172)
- Support index customization and index templates [#168](https://github.com/plotly/dashR/pull/168)
- Application titles may be set using the `app$title()` method, for parity with Dash for Python's `app.title` syntax [#168](https://github.com/plotly/dashR/pull/168)

### Changed
- Dash for R now requires `dashCoreComponents` v1.8.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The table version bump should also be mentioned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in c03c6c1

- Dash for R now requires `dashTable` v4.6.0
- Automatically set routes and requests pathname prefixes if `DASH_APP_NAME` environment variable has been set [#165](https://github.com/plotly/dashR/pull/165)

### Deprecated
- Application titles can no longer be set using `name` parameter, which is now deprecated with a warning, for parity with Dash for Python [#168](https://github.com/plotly/dashR/pull/168)
- Removed `DASH_HOST` and `DASH_PORT`, Dash for R now respects `HOST` and `PORT` [#167](https://github.com/plotly/dashR/pull/167)

## [0.2.0] - 2020-01-03
### Added
- Support for asynchronous/dynamic loading of dependencies, resource caching, and asset fingerprinting [#157](https://github.com/plotly/dashR/pull/157)
Expand Down Expand Up @@ -28,6 +44,7 @@ All notable changes to this project will be documented in this file.
- Fixes for hot reloading interval handling and refreshing apps within viewer pane [#148](https://github.com/plotly/dashR/pull/148)
- `get_asset_url` checks `getAppPath()` as well as `DASH_APP_ROOT_PATH` environment variable when invoked [#161](https://github.com/plotly/dashR/pull/161)


## [0.1.0] - 2019-07-10
### Added
- Initial release
Expand Down
12 changes: 6 additions & 6 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
Package: dash
Title: An Interface to the Dash Ecosystem for Authoring Reactive Web Applications
Version: 0.2.0
Authors@R: c(person("Chris", "Parmer", role = c("aut"), email = "[email protected]"), person("Ryan Patrick", "Kyle", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-5829-9867"), email = "[email protected]"), person("Carson", "Sievert", role = c("aut"), comment = c(ORCID = "0000-0002-4958-2844")), person(family = "Plotly Technologies", role = "cph"))
Version: 0.3.0
Authors@R: c(person("Chris", "Parmer", role = c("aut"), email = "[email protected]"), person("Ryan Patrick", "Kyle", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-5829-9867"), email = "[email protected]"), person("Carson", "Sievert", role = c("aut"), comment = c(ORCID = "0000-0002-4958-2844")), person("Hammad", "Khan", role = c("aut"), email = "[email protected]"), person(family = "Plotly Technologies", role = "cph"))
Description: A framework for building analytical web applications, Dash offers a pleasant and productive development experience. No JavaScript required.
Depends:
R (>= 3.0.2)
Imports:
dashHtmlComponents (== 1.0.2),
dashCoreComponents (== 1.6.0),
dashTable (== 4.5.1),
dashCoreComponents (== 1.8.0),
dashTable (== 4.6.0),
R6,
fiery (> 1.0.0),
routr (> 0.2.0),
Expand All @@ -32,8 +32,8 @@ Collate:
'print.R'
'internal.R'
Remotes: plotly/dash-html-components@55c3884,
plotly/dash-core-components@c107e0f,
plotly/dash-table@3058bd5
plotly/dash-core-components@fc153b4,
plotly/dash-table@79d46ca
License: MIT + file LICENSE
Encoding: UTF-8
LazyData: true
Expand Down
236 changes: 203 additions & 33 deletions R/dash.R

Large diffs are not rendered by default.

93 changes: 84 additions & 9 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -457,22 +457,25 @@ valid_seq <- function(params) {
}
}

resolve_prefix <- function(prefix, environment_var, base_pathname) {
resolvePrefix <- function(prefix, environment_var, base_pathname) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering why this function is changed to camelCase when many other functions are snake_case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to open a PR to migrate all functions to camelCase and variables to snake_case, which follows the generally accepted style rules for R. That will likely occur within the next week, prior to CRAN submission.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cf. https://google.github.io/styleguide/Rguide.html, though they use Pascal case instead of camel case, and maybe we should also. 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kk, thx. Pick one, enforce it. Move on :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:neckbeard: 📘 🤺

if (!(is.null(prefix))) {
assertthat::assert_that(is.character(prefix))

return(prefix)
} else {
# Check environment variables
prefix_env <- Sys.getenv(environment_var)
if (prefix_env != "") {
env_base_pathname <- Sys.getenv("DASH_URL_BASE_PATHNAME")
app_name <- Sys.getenv("DASH_APP_NAME")

if (prefix_env != "")
return(prefix_env)
} else {
env_base_pathname <- Sys.getenv("DASH_URL_BASE_PATHNAME")
if (env_base_pathname != "")
return(env_base_pathname)
else
return(base_pathname)
}
else if (app_name != "")
return(sprintf("/%s/", app_name))
else if (env_base_pathname != "")
return(env_base_pathname)
else
return(base_pathname)
}
}

Expand Down Expand Up @@ -1267,3 +1270,75 @@ tryCompress <- function(request, response) {
}
return(response$compress())
}

get_relative_path <- function(requests_pathname, path) {
# Returns a path with the config setting 'requests_pathname_prefix' prefixed to
# it. This is particularly useful for apps deployed on Dash Enterprise, which makes
# it easier to serve apps under both URL prefixes and localhost.

if (requests_pathname == "/" && path == "") {
return("/")
}
else if (requests_pathname != "/" && path == "") {
return(requests_pathname)
}
else if (!startsWith(path, "/")) {
stop(sprintf(paste0("Unsupported relative path! Paths that aren't prefixed" ,
"with a leading '/' are not supported. You supplied '%s'."),
path))
}
else {
return(paste(gsub("/$", "", requests_pathname), gsub("^/", "", path), sep = "/"))
}
}

strip_relative_path <- function(requests_pathname, path) {
# Returns a relative path with the `requests_pathname_prefix` and leadings and trailing
# slashes stripped from it. This function is particularly relevant to dccLocation pathname routing.

if (is.null(path)) {
return(NULL)
}
else if ((requests_pathname != "/" && !startsWith(path, gsub("/$", "", requests_pathname)))
|| (requests_pathname == "/" && !startsWith(path, "/"))) {
stop(sprintf(paste0("Unsupported relative path! Path's that are not prefixed ",
"with a leading 'requests_pathname_prefix` are not suported. ",
"You supplied '%s', and requests_pathname_prefix was '%s'."),
path, requests_pathname
))
}
else if (requests_pathname != "/" && startsWith(path, gsub("/$", "", requests_pathname))) {
path = sub(gsub("/$", "", requests_pathname), "", path)
}
return(trimws(gsub("/", "", path)))
}

interpolate_str <- function(index_template, ...) {
# This function takes an index string, along with
# user specified keys for the html keys of the index
# and sets the default values of the keys to the
# ones specified by the keys themselves, returning
# the custom index template.
template = index_template
kwargs <- list(...)

for (name in names(kwargs)) {
key = paste0('\\{', name, '\\}')

template = sub(key, kwargs[[name]], template)
}
return(template)
}

validate_keys <- function(string) {
required_keys <- c("app_entry", "config", "scripts")

keys_present <- vapply(required_keys, function(x) grepl(x, string), logical(1))

if (!all(keys_present)) {
stop(sprintf("Did you forget to include %s in your index string?",
paste(names(keys_present[keys_present==FALSE]), collapse = ", ")))
} else {
return(string)
}
}
69 changes: 64 additions & 5 deletions man/Dash.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions man/dash-package.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Authors:
\item Chris Parmer \email{[email protected]}
\item Ryan Patrick Kyle \email{[email protected]}
\item Carson Sievert
\item Hammad Khan \email{[email protected]}
}

Other contributors:
Expand Down
55 changes: 55 additions & 0 deletions tests/integration/test_name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
named_app = """
library(dash)
library(dashHtmlComponents)
app <- Dash$new()

app$title("Testing")

app$layout(htmlDiv(list(htmlDiv(id='container',children='Hello Dash for R testing'))))
app$run_server()
"""

app_with_template = """
library(dash)
library(dashHtmlComponents)
app <- Dash$new()

string <-
"<!DOCTYPE html>
<html>
<head>
{%meta_tags%}
<title>Testing Again</title>
Copy link
Contributor

@Marc-Andre-Rivet Marc-Andre-Rivet Feb 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you set both app$title and the template? The template wins? Maybe adding some default title app$title("On no! Not again!") in this test makes that behavior more obvious.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you set app$title, it wins. I suspect this is what we want, rather than the template taking precedence, though I cannot say for sure.

{%favicon%}
{%css_tags%}
</head>
<body>
{%app_entry%}
<footer>
{%config%}
{%scripts%}
</footer>
</body>
</html>"

app$index_string(string)

app$layout(htmlDiv(list(htmlDiv(id='container',children='Hello Dash for R testing'))))
app$run_server()
"""


def test_rapp001r_with_appname(dashr):
dashr.start_server(named_app)
dashr.wait_for_text_to_equal(
"#container", "Hello Dash for R testing", timeout=1
)
assert dashr.find_element("title").get_attribute("text") == "Testing"


def test_rapp002_r_with_template(dashr):
dashr.start_server(app_with_template)
dashr.wait_for_text_to_equal(
"#container", "Hello Dash for R testing", timeout=1
)
assert dashr.find_element("title").get_attribute("text") == "Testing Again"
Loading