Skip to content

feat: Added product environment check helpers #372

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: local::., any::lintr, any::devtools, any::testthat
extra-packages: local::., any::lintr, any::devtools, any::testthat, any::cyclocomp
needs: lint

- name: Lint
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# connectapi (development version)

## New features

- New functions `get_product()`, `is_local()`, `on_connect()` (updated), and `on_workbench()` help detect the Posit product environment (Posit Connect, Posit Workbench, or local) via environment variables. `get_product()` checks both `POSIT_PRODUCT` and `RSTUDIO_PRODUCT` environment variables. (#371)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since this is the first time on_connect() will be exported, it's actually "new" and not updated.

Suggested change
- New functions `get_product()`, `is_local()`, `on_connect()` (updated), and `on_workbench()` help detect the Posit product environment (Posit Connect, Posit Workbench, or local) via environment variables. `get_product()` checks both `POSIT_PRODUCT` and `RSTUDIO_PRODUCT` environment variables. (#371)
- New functions `get_product()`, `is_local()`, `on_connect()`, and `on_workbench()` help detect the Posit product environment (Posit Connect, Posit Workbench, or local) via environment variables. `get_product()` checks both `POSIT_PRODUCT` and `RSTUDIO_PRODUCT` environment variables. (#371)


# connectapi 0.6.0

## New features
Expand Down
24 changes: 22 additions & 2 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,28 @@ endpoint_does_not_exist <- function(res) {
!("code" %in% names(httr::content(res, as = "parsed")))
}

get_product <- function() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Functions that we wanna export as part of the package namespace (i.e. loaded when running library(connectapi) should have roxygen2 documentation, and that documentation must contain the @export tag. A good pretty light example to look at is the get_runtimes() documentation here. (Except for those docs contain a blank line, which — while it doesn't cause problems — is a mistake.)

roxygen2 docs are preceded by #' and follow this general form (this is the block for get_runtimes().

#' Get available runtimes on server
#'
#' Get a table showing available versions of R, Python, Quarto, and Tensorflow
#' on the Connect server.
#'
#' @param client A `Connect` object.
#' @param runtimes Optional. A character vector of runtimes to include. Must be
#' some combination of `"r"`, `"python"`, `"quarto"`, and `"tensorflow"`. Quarto
#' is only supported on Connect >= 2021.08.0, and Tensorflow is only supported
#' on Connect >= 2024.03.0.
#' @return A tibble with columns for `runtime`, `version`, and `cluster_name`
#' and `image_name`. Cluster name and image name are only meaningful on Connect
#' instances running off-host execution.
#'
#' @examples
#' \dontrun{
#' library(connectapi)
#' client <- connect()
#' get_runtimes(client, runtimes = c("r", "python", "tensorflow"))
#' }
#'
#' @export

These won't need much. In fact, they could be listed on the same documentation page. To do that, you'd follow the pattern with get_jobs() (see here). There, the return values for multiple content items are described i.e. (excerpt):

#' @return
#'
#' - `get_jobs()`: A data frame with a row representing each job.
#' - `get_job_list()`: A list with each element representing a job.

and the end of the documentation includes the @rdname tag

#' @rdname get_jobs
#' @export

Other functions can then include just those same two lines as their documentation to show the same help page when queried (e.g. get_job_list() further down in the file).

That explanation is a little terse — let me know if you have any other questions!

posit_product <- Sys.getenv("POSIT_PRODUCT")
if (posit_product != "") {
return(posit_product)
}
Sys.getenv("RSTUDIO_PRODUCT")
}

# Returns `TRUE` if we're running locally (no product env var set),
# else `FALSE`.
is_local <- function() {
get_product() == ""
}

# Returns `TRUE` if we're running on Connect as determined by the
# `RSTUDIO_PRODUCT` env var, else `FALSE`.
# `POSIT_PRODUCT` or `RSTUDIO_PRODUCT` env var, else `FALSE`.
on_connect <- function() {
Sys.getenv("RSTUDIO_PRODUCT") == "CONNECT"
get_product() == "CONNECT"
}

# Returns `TRUE` if we're running on Workbench as determined by the
# `POSIT_PRODUCT` or `RSTUDIO_PRODUCT` env var, else `FALSE`.
on_workbench <- function() {
get_product() == "WORKBENCH"
}
43 changes: 41 additions & 2 deletions tests/testthat/test-connect.R
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ test_that("Visitor client can successfully be created running on Connect", {
withr::local_envvar(
CONNECT_SERVER = "https://connect.example",
CONNECT_API_KEY = "fake",
RSTUDIO_PRODUCT = "CONNECT"
POSIT_PRODUCT = "CONNECT"
)

client <- connect(token = "my-token")
Expand Down Expand Up @@ -181,7 +181,7 @@ test_that("Visitor client code path errs with older Connect version", {
withr::local_envvar(
CONNECT_SERVER = "https://connect.example",
CONNECT_API_KEY = "fake",
RSTUDIO_PRODUCT = "CONNECT"
POSIT_PRODUCT = "CONNECT"
)

expect_error(
Expand All @@ -190,3 +190,42 @@ test_that("Visitor client code path errs with older Connect version", {
)
})
})

test_that("environment detection functions work", {
withr::with_envvar(c(POSIT_PRODUCT = "", RSTUDIO_PRODUCT = ""), {
expect_true(is_local())
expect_false(on_connect())
expect_false(on_workbench())
})

withr::with_envvar(c(POSIT_PRODUCT = "CONNECT", RSTUDIO_PRODUCT = ""), {
expect_false(is_local())
expect_true(on_connect())
expect_false(on_workbench())
})

withr::with_envvar(c(POSIT_PRODUCT = "WORKBENCH", RSTUDIO_PRODUCT = ""), {
expect_false(is_local())
expect_false(on_connect())
expect_true(on_workbench())
})

withr::with_envvar(c(POSIT_PRODUCT = "", RSTUDIO_PRODUCT = "CONNECT"), {
expect_false(is_local())
expect_true(on_connect())
expect_false(on_workbench())
})

withr::with_envvar(c(POSIT_PRODUCT = "", RSTUDIO_PRODUCT = "WORKBENCH"), {
expect_false(is_local())
expect_false(on_connect())
expect_true(on_workbench())
})

# POSIT_PRODUCT takes precedence over RSTUDIO_PRODUCT
withr::with_envvar(c(POSIT_PRODUCT = "CONNECT", RSTUDIO_PRODUCT = "WORKBENCH"), {
expect_false(is_local())
expect_true(on_connect())
expect_false(on_workbench())
})
})
Loading