From 93c38c4f3bbbd08152ad0c39284817818ea7a2da Mon Sep 17 00:00:00 2001 From: Bruno Tremblay Date: Sat, 25 Nov 2023 14:09:19 -0500 Subject: [PATCH 1/4] Allow to set plumber options using environment variables `?options_plumber`. --- NAMESPACE | 1 + NEWS.md | 1 + R/options_plumber.R | 25 ++++++++++++++++++++++++- R/plumber.R | 14 +++++++------- R/pr.R | 2 +- R/pr_set.R | 4 ++-- R/shared-secret-filter.R | 4 ++-- R/ui.R | 16 ++++++++-------- man/Plumber.Rd | 8 +++++--- man/options_plumber.Rd | 13 ++++++++++++- man/pr_run.Rd | 2 +- man/pr_set_docs.Rd | 2 +- man/pr_set_docs_callback.Rd | 5 ++++- tests/testthat/test-options.R | 23 ++++++++++++++++------- tests/testthat/test-plumber-run.R | 4 ++-- 15 files changed, 87 insertions(+), 37 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 2cd288b35..2047ecaed 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -18,6 +18,7 @@ export(do_remove_forward) export(endpoint_serializer) export(forward) export(getCharacterSet) +export(getOption_env_default) export(get_character_set) export(include_file) export(include_html) diff --git a/NEWS.md b/NEWS.md index 28803a943..de7074afc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # plumber (development version) +* Allow to set plumber options using environment variables `?options_plumber`. (@meztez #934) * Add support for quoted boundary for multipart request parsing. (@meztez #924) * Fix #916, related to `parseUTF8` return value attribute `srcfile` on Windows. (#930) diff --git a/R/options_plumber.R b/R/options_plumber.R index 94f4ff5a4..1b91550a1 100644 --- a/R/options_plumber.R +++ b/R/options_plumber.R @@ -2,7 +2,9 @@ #' #' There are a number of global options that affect Plumber's behavior. These can #' be set globally with [options()] or with [options_plumber()]. Options set using -#' [options_plumber()] should not include the `plumber.` prefix. +#' [options_plumber()] should not include the `plumber.` prefix. Alternatively, +#' environment variable can be used to set plumber options using uppercase and +#' underscores (i.e. to set `plumber.apiHost` you can set environment variable `PLUMBER_APIHOST`). #' #' \describe{ #' \item{`plumber.port`}{Port Plumber will attempt to use to start http server. @@ -89,3 +91,24 @@ options_plumber <- function( plumber.legacyRedirects = legacyRedirects ) } + +#' Get an option value, alternatively look in environment for value +#' @rdname options_plumber +#' @inheritParams base::options +#' @export +getOption_env_default <- function(x, default = NULL) { + + getOption(x, default = { + env_name <- toupper(chartr(".", "_", x)) + res <- Sys.getenv(env_name) + if (res == "") { + default + } else { + if (res %in% c("TRUE", "FALSE")) { + return(as.logical(res)) + } + res + } + }) + +} diff --git a/R/plumber.R b/R/plumber.R index 03cefd730..a0980ea7c 100644 --- a/R/plumber.R +++ b/R/plumber.R @@ -159,7 +159,7 @@ Plumber <- R6Class( #' @importFrom rlang missing_arg run = function( host = '127.0.0.1', - port = getOption('plumber.port', NULL), + port = getOption_env_default('plumber.port', NULL), swagger = deprecated(), debug = missing_arg(), swaggerCallback = missing_arg(), @@ -211,7 +211,7 @@ Plumber <- R6Class( port <- findPort(port) # Delay setting max size option. It could be set in `plumber.R`, which is after initialization - private$maxSize <- getOption('plumber.maxRequestSize', 0) #0 Unlimited + private$maxSize <- getOption_env_default('plumber.maxRequestSize', 0) #0 Unlimited # Delay the setting of swaggerCallback as long as possible. # An option could be set in `plumber.R`, which is after initialization @@ -219,7 +219,7 @@ Plumber <- R6Class( swaggerCallback <- rlang::maybe_missing(swaggerCallback, rlang::maybe_missing(private$docs_callback, - getOption('plumber.docs.callback', getOption('plumber.swagger.url', NULL)) + getOption_env_default('plumber.docs.callback', getOption_env_default('plumber.swagger.url', NULL)) ) ) @@ -784,7 +784,7 @@ Plumber <- R6Class( # No endpoint could handle this request. 404 notFoundStep <- function(...) { - if (isTRUE(getOption("plumber.trailingSlash", FALSE))) { + if (isTRUE(getOption_env_default("plumber.trailingSlash", FALSE))) { # Redirect to the slash route, if it exists path <- req$PATH_INFO # If the path does not end in a slash, @@ -813,7 +813,7 @@ Plumber <- R6Class( # No trailing-slash route exists... # Try allowed verbs - if (isTRUE(getOption("plumber.methodNotAllowed", TRUE))) { + if (isTRUE(getOption_env_default("plumber.methodNotAllowed", TRUE))) { # Notify about allowed verbs if (is_405(req$pr, req$PATH_INFO, req$REQUEST_METHOD)) { res$status <- 405L @@ -933,7 +933,7 @@ Plumber <- R6Class( #' If using [options_plumber()], the value must be set before initializing your Plumber router. #' @param ... Arguments for the visual documentation. See each visual documentation package for further details. setDocs = function( - docs = getOption("plumber.docs", TRUE), + docs = getOption_env_default("plumber.docs", TRUE), ... ) { private$docs_info <- upgrade_docs_parameter(docs, ...) @@ -948,7 +948,7 @@ Plumber <- R6Class( #' See also: [pr_set_docs_callback()] #' @param callback a callback function for taking action on the docs url. (Also accepts `NULL` values to disable the `callback`.) setDocsCallback = function( - callback = getOption('plumber.docs.callback', NULL) + callback = getOption_env_default('plumber.docs.callback', NULL) ) { # Use callback when defined if (!length(callback) || !is.function(callback)) { diff --git a/R/pr.R b/R/pr.R index 40f1b4be0..4704242a2 100644 --- a/R/pr.R +++ b/R/pr.R @@ -520,7 +520,7 @@ pr_filter <- function(pr, #' @export pr_run <- function(pr, host = '127.0.0.1', - port = getOption('plumber.port', NULL), + port = getOption_env_default('plumber.port', NULL), ..., debug = missing_arg(), docs = missing_arg(), diff --git a/R/pr_set.R b/R/pr_set.R index dd66561f9..d10442e15 100644 --- a/R/pr_set.R +++ b/R/pr_set.R @@ -177,7 +177,7 @@ pr_set_debug <- function(pr, debug = interactive()) { #' } pr_set_docs <- function( pr, - docs = getOption("plumber.docs", TRUE), + docs = getOption_env_default("plumber.docs", TRUE), ... ) { validate_pr(pr) @@ -206,7 +206,7 @@ pr_set_docs <- function( #' } pr_set_docs_callback <- function( pr, - callback = getOption('plumber.docs.callback', NULL) + callback = getOption_env_default('plumber.docs.callback', NULL) ) { validate_pr(pr) pr$setDocsCallback(callback = callback) diff --git a/R/shared-secret-filter.R b/R/shared-secret-filter.R index 0e508f2b4..c709c1c5e 100644 --- a/R/shared-secret-filter.R +++ b/R/shared-secret-filter.R @@ -1,6 +1,6 @@ #' @noRd sharedSecretFilter <- function(req, res){ - secret <- getOption("plumber.sharedSecret", NULL) + secret <- getOption_env_default("plumber.sharedSecret", NULL) if (!is.null(secret)){ supplied <- req$HTTP_PLUMBER_SHARED_SECRET if (!identical(supplied, secret)){ @@ -9,7 +9,7 @@ sharedSecretFilter <- function(req, res){ res$serializer <- serializer_unboxed_json() # Using output similar to `defaultErrorHandler()` li <- list(error = "400 - Bad request") - + # Don't overly leak data unless they opt-in if (is.function(req$pr$getDebug) && isTRUE(req$pr$getDebug())) { li$message <- "Shared secret mismatch" diff --git a/R/ui.R b/R/ui.R index 65a562d80..db5701cf5 100644 --- a/R/ui.R +++ b/R/ui.R @@ -10,13 +10,13 @@ mount_docs <- function(pr, host, port, docs_info, callback, quiet = FALSE) { } # Build api url - api_url <- getOption( + api_url <- getOption_env_default( "plumber.apiURL", urlHost( - scheme = getOption("plumber.apiScheme", "http"), - host = getOption("plumber.apiHost", host), - port = getOption("plumber.apiPort", port), - path = getOption("plumber.apiPath", ""), + scheme = getOption_env_default("plumber.apiScheme", "http"), + host = getOption_env_default("plumber.apiHost", host), + port = getOption_env_default("plumber.apiPort", port), + path = getOption_env_default("plumber.apiPath", ""), changeHostLocation = TRUE ) ) @@ -91,8 +91,8 @@ mount_openapi <- function(pr, api_url) { openapi_fun <- function(req) { # use the HTTP_REFERER so RSC can find the Docs location to ask ## (can't directly ask for 127.0.0.1) - if (is.null(getOption("plumber.apiURL")) && - is.null(getOption("plumber.apiHost"))) { + if (is.null(getOption_env_default("plumber.apiURL")) && + is.null(getOption_env_default("plumber.apiHost"))) { if (is.null(req$HTTP_REFERER)) { # Prevent leaking host and port if option is not set api_url <- character(1) @@ -256,7 +256,7 @@ registered_docs <- function() { swagger_redirects <- function() { - if (!isTRUE(getOption("plumber.legacyRedirects", TRUE))) { + if (!isTRUE(getOption_env_default("plumber.legacyRedirects", TRUE))) { return(list()) } diff --git a/man/Plumber.Rd b/man/Plumber.Rd index 576d47c8e..16e5026f9 100644 --- a/man/Plumber.Rd +++ b/man/Plumber.Rd @@ -217,7 +217,7 @@ See also: \code{\link[=pr_run]{pr_run()}} \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Plumber$run( host = "127.0.0.1", - port = getOption("plumber.port", NULL), + port = getOption_env_default("plumber.port", NULL), swagger = deprecated(), debug = missing_arg(), swaggerCallback = missing_arg(), @@ -740,7 +740,7 @@ Set visual documentation to use for API See also: \code{\link[=pr_set_docs]{pr_set_docs()}}, \code{\link[=register_docs]{register_docs()}}, \code{\link[=registered_docs]{registered_docs()}} \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{Plumber$setDocs(docs = getOption("plumber.docs", TRUE), ...)}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{Plumber$setDocs(docs = getOption_env_default("plumber.docs", TRUE), ...)}\if{html}{\out{
}} } \subsection{Arguments}{ @@ -767,7 +767,9 @@ If using \code{\link[=options_plumber]{options_plumber()}}, the value must be se See also: \code{\link[=pr_set_docs_callback]{pr_set_docs_callback()}} \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{Plumber$setDocsCallback(callback = getOption("plumber.docs.callback", NULL))}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{Plumber$setDocsCallback( + callback = getOption_env_default("plumber.docs.callback", NULL) +)}\if{html}{\out{
}} } \subsection{Arguments}{ diff --git a/man/options_plumber.Rd b/man/options_plumber.Rd index ef2b717fb..96de17f12 100644 --- a/man/options_plumber.Rd +++ b/man/options_plumber.Rd @@ -2,6 +2,7 @@ % Please edit documentation in R/options_plumber.R \name{options_plumber} \alias{options_plumber} +\alias{getOption_env_default} \title{Plumber options} \usage{ options_plumber( @@ -20,11 +21,19 @@ options_plumber( sharedSecret = getOption("plumber.sharedSecret"), legacyRedirects = getOption("plumber.legacyRedirects") ) + +getOption_env_default(x, default = NULL) } \arguments{ \item{...}{Ignored. Should be empty} \item{port, docs, docs.callback, trailingSlash, methodNotAllowed, apiScheme, apiHost, apiPort, apiPath, apiURL, maxRequestSize, sharedSecret, legacyRedirects}{See details} + +\item{x}{a character string holding an option name.} + +\item{default}{if the specified option is not set in the options list, + this value is returned. This facilitates retrieving an option and + checking whether it is set and setting it separately if not.} } \value{ The complete, prior set of \code{\link[=options]{options()}} values. @@ -34,7 +43,9 @@ If no parameters are supplied, all returned values will be the current \code{\li \description{ There are a number of global options that affect Plumber's behavior. These can be set globally with \code{\link[=options]{options()}} or with \code{\link[=options_plumber]{options_plumber()}}. Options set using -\code{\link[=options_plumber]{options_plumber()}} should not include the \code{plumber.} prefix. +\code{\link[=options_plumber]{options_plumber()}} should not include the \code{plumber.} prefix. Alternatively, +environment variable can be used to set plumber options using uppercase and +underscores (i.e. to set \code{plumber.apiHost} you can set environment variable \code{PLUMBER_APIHOST}). } \details{ \describe{ diff --git a/man/pr_run.Rd b/man/pr_run.Rd index e674b7ed4..679048d07 100644 --- a/man/pr_run.Rd +++ b/man/pr_run.Rd @@ -7,7 +7,7 @@ pr_run( pr, host = "127.0.0.1", - port = getOption("plumber.port", NULL), + port = getOption_env_default("plumber.port", NULL), ..., debug = missing_arg(), docs = missing_arg(), diff --git a/man/pr_set_docs.Rd b/man/pr_set_docs.Rd index 1063db801..ca4275e00 100644 --- a/man/pr_set_docs.Rd +++ b/man/pr_set_docs.Rd @@ -4,7 +4,7 @@ \alias{pr_set_docs} \title{Set the API visual documentation} \usage{ -pr_set_docs(pr, docs = getOption("plumber.docs", TRUE), ...) +pr_set_docs(pr, docs = getOption_env_default("plumber.docs", TRUE), ...) } \arguments{ \item{pr}{A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function.} diff --git a/man/pr_set_docs_callback.Rd b/man/pr_set_docs_callback.Rd index 25a4dc56a..28ee2af34 100644 --- a/man/pr_set_docs_callback.Rd +++ b/man/pr_set_docs_callback.Rd @@ -4,7 +4,10 @@ \alias{pr_set_docs_callback} \title{Set the \code{callback} to tell where the API visual documentation is located} \usage{ -pr_set_docs_callback(pr, callback = getOption("plumber.docs.callback", NULL)) +pr_set_docs_callback( + pr, + callback = getOption_env_default("plumber.docs.callback", NULL) +) } \arguments{ \item{pr}{A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function.} diff --git a/tests/testthat/test-options.R b/tests/testthat/test-options.R index 8fa6e53af..8d6b7c4ac 100644 --- a/tests/testthat/test-options.R +++ b/tests/testthat/test-options.R @@ -3,9 +3,18 @@ context("Options") test_that("Options set and get", { with_options(list(plumber.port = NULL), { options_plumber(port = FALSE) - expect_false(getOption("plumber.port")) + expect_false(getOption_env_default("plumber.port")) options_plumber(port = NULL) - expect_null(getOption("plumber.port")) + expect_null(getOption_env_default("plumber.port")) + }) +}) + +test_that("Options set and get", { + with_options(list(plumber.port = NULL), { + Sys.setenv("PLUMBER_PORT" = FALSE) + expect_false(getOption_env_default("plumber.port")) + Sys.unsetenv("PLUMBER_PORT") + expect_null(getOption_env_default("plumber.port")) }) }) @@ -28,7 +37,7 @@ test_that("all options used are `options_plumber()` parameters", { file_content <- paste0(readLines(r_file, warn = F), collapse = "") match <- stringi::stri_match_all_regex(file_content, "getOption\\([^,\\)]+,?\\)?")[[1]][,1] match <- gsub("\\s", "", match) - if (length(match) > 0 && !is.na(match)) { + if (length(match) > 0 && !all(is.na(match))) { matches <- c(matches, match) } } @@ -54,7 +63,7 @@ test_that("all options used are `options_plumber()` parameters", { test_that("Legacy swagger redirect can be disabled", { with_options( list( - plumber.legacyRedirets = getOption("plumber.legacyRedirects") + plumber.legacyRedirets = getOption_env_default("plumber.legacyRedirects") ), { options_plumber(legacyRedirects = TRUE) redirects <- swagger_redirects() @@ -70,12 +79,12 @@ test_that("Legacy swagger redirect can be disabled", { test_that("docs.callback sync plumber.swagger.url", { with_options( list( - plumber.swagger.url = getOption("plumber.swagger.url"), - plumber.docs.callback = getOption("plumber.docs.callback") + plumber.swagger.url = getOption_env_default("plumber.swagger.url"), + plumber.docs.callback = getOption_env_default("plumber.docs.callback") ), { options("plumber.swagger.url" = function(api_url) {cat(api_url)}) opt <- options_plumber(docs.callback = NULL) - expect_null(getOption("plumber.swagger.url")) + expect_null(getOption_env_default("plumber.swagger.url")) expect_null(opt$plumber.docs.callback) } ) diff --git a/tests/testthat/test-plumber-run.R b/tests/testthat/test-plumber-run.R index ffdf829bf..fe2ebd05a 100644 --- a/tests/testthat/test-plumber-run.R +++ b/tests/testthat/test-plumber-run.R @@ -77,8 +77,8 @@ test_that("`swaggerCallback` can be set by option after the pr is created", { with_options( list( - plumber.swagger.url = getOption("plumber.swagger.url"), - plumber.docs.callback = getOption("plumber.docs.callback") + plumber.swagger.url = getOption_env_default("plumber.swagger.url"), + plumber.docs.callback = getOption_env_default("plumber.docs.callback") ), { # set option after init From 2bcce38423adb8aba47b07fdeaa13ce07bf8209a Mon Sep 17 00:00:00 2001 From: Bruno Tremblay Date: Mon, 27 Nov 2023 15:26:53 -0500 Subject: [PATCH 2/4] PR review changes --- NAMESPACE | 2 +- R/options_plumber.R | 15 +++++++-------- R/plumber.R | 14 +++++++------- R/pr.R | 2 +- R/pr_set.R | 4 ++-- R/shared-secret-filter.R | 2 +- R/ui.R | 16 ++++++++-------- man/Plumber.Rd | 6 +++--- man/options_plumber.Rd | 9 +++++++-- man/pr_run.Rd | 2 +- man/pr_set_docs.Rd | 2 +- man/pr_set_docs_callback.Rd | 2 +- tests/testthat/test-options.R | 16 ++++++++-------- tests/testthat/test-plumber-run.R | 4 ++-- 14 files changed, 50 insertions(+), 46 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 2047ecaed..e0773c28e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -18,8 +18,8 @@ export(do_remove_forward) export(endpoint_serializer) export(forward) export(getCharacterSet) -export(getOption_env_default) export(get_character_set) +export(get_option_or_env) export(include_file) export(include_html) export(include_md) diff --git a/R/options_plumber.R b/R/options_plumber.R index 1b91550a1..5fa25d8c4 100644 --- a/R/options_plumber.R +++ b/R/options_plumber.R @@ -93,22 +93,21 @@ options_plumber <- function( } #' Get an option value, alternatively look in environment for value -#' @rdname options_plumber +#' @describeIn options_plumber DOCS #' @inheritParams base::options #' @export -getOption_env_default <- function(x, default = NULL) { +get_option_or_env <- function(x, default = NULL) { getOption(x, default = { env_name <- toupper(chartr(".", "_", x)) res <- Sys.getenv(env_name) if (res == "") { - default - } else { - if (res %in% c("TRUE", "FALSE")) { - return(as.logical(res)) - } - res + return(default) } + if (res %in% c("TRUE", "FALSE")) { + return(as.logical(res)) + } + res }) } diff --git a/R/plumber.R b/R/plumber.R index a0980ea7c..9050b46a2 100644 --- a/R/plumber.R +++ b/R/plumber.R @@ -159,7 +159,7 @@ Plumber <- R6Class( #' @importFrom rlang missing_arg run = function( host = '127.0.0.1', - port = getOption_env_default('plumber.port', NULL), + port = get_option_or_env('plumber.port', NULL), swagger = deprecated(), debug = missing_arg(), swaggerCallback = missing_arg(), @@ -211,7 +211,7 @@ Plumber <- R6Class( port <- findPort(port) # Delay setting max size option. It could be set in `plumber.R`, which is after initialization - private$maxSize <- getOption_env_default('plumber.maxRequestSize', 0) #0 Unlimited + private$maxSize <- get_option_or_env('plumber.maxRequestSize', 0) #0 Unlimited # Delay the setting of swaggerCallback as long as possible. # An option could be set in `plumber.R`, which is after initialization @@ -219,7 +219,7 @@ Plumber <- R6Class( swaggerCallback <- rlang::maybe_missing(swaggerCallback, rlang::maybe_missing(private$docs_callback, - getOption_env_default('plumber.docs.callback', getOption_env_default('plumber.swagger.url', NULL)) + get_option_or_env('plumber.docs.callback', get_option_or_env('plumber.swagger.url', NULL)) ) ) @@ -784,7 +784,7 @@ Plumber <- R6Class( # No endpoint could handle this request. 404 notFoundStep <- function(...) { - if (isTRUE(getOption_env_default("plumber.trailingSlash", FALSE))) { + if (isTRUE(get_option_or_env("plumber.trailingSlash", FALSE))) { # Redirect to the slash route, if it exists path <- req$PATH_INFO # If the path does not end in a slash, @@ -813,7 +813,7 @@ Plumber <- R6Class( # No trailing-slash route exists... # Try allowed verbs - if (isTRUE(getOption_env_default("plumber.methodNotAllowed", TRUE))) { + if (isTRUE(get_option_or_env("plumber.methodNotAllowed", TRUE))) { # Notify about allowed verbs if (is_405(req$pr, req$PATH_INFO, req$REQUEST_METHOD)) { res$status <- 405L @@ -933,7 +933,7 @@ Plumber <- R6Class( #' If using [options_plumber()], the value must be set before initializing your Plumber router. #' @param ... Arguments for the visual documentation. See each visual documentation package for further details. setDocs = function( - docs = getOption_env_default("plumber.docs", TRUE), + docs = get_option_or_env("plumber.docs", TRUE), ... ) { private$docs_info <- upgrade_docs_parameter(docs, ...) @@ -948,7 +948,7 @@ Plumber <- R6Class( #' See also: [pr_set_docs_callback()] #' @param callback a callback function for taking action on the docs url. (Also accepts `NULL` values to disable the `callback`.) setDocsCallback = function( - callback = getOption_env_default('plumber.docs.callback', NULL) + callback = get_option_or_env('plumber.docs.callback', NULL) ) { # Use callback when defined if (!length(callback) || !is.function(callback)) { diff --git a/R/pr.R b/R/pr.R index 4704242a2..b9f302c9d 100644 --- a/R/pr.R +++ b/R/pr.R @@ -520,7 +520,7 @@ pr_filter <- function(pr, #' @export pr_run <- function(pr, host = '127.0.0.1', - port = getOption_env_default('plumber.port', NULL), + port = get_option_or_env('plumber.port', NULL), ..., debug = missing_arg(), docs = missing_arg(), diff --git a/R/pr_set.R b/R/pr_set.R index d10442e15..a62c81585 100644 --- a/R/pr_set.R +++ b/R/pr_set.R @@ -177,7 +177,7 @@ pr_set_debug <- function(pr, debug = interactive()) { #' } pr_set_docs <- function( pr, - docs = getOption_env_default("plumber.docs", TRUE), + docs = get_option_or_env("plumber.docs", TRUE), ... ) { validate_pr(pr) @@ -206,7 +206,7 @@ pr_set_docs <- function( #' } pr_set_docs_callback <- function( pr, - callback = getOption_env_default('plumber.docs.callback', NULL) + callback = get_option_or_env('plumber.docs.callback', NULL) ) { validate_pr(pr) pr$setDocsCallback(callback = callback) diff --git a/R/shared-secret-filter.R b/R/shared-secret-filter.R index c709c1c5e..9e3f72eed 100644 --- a/R/shared-secret-filter.R +++ b/R/shared-secret-filter.R @@ -1,6 +1,6 @@ #' @noRd sharedSecretFilter <- function(req, res){ - secret <- getOption_env_default("plumber.sharedSecret", NULL) + secret <- get_option_or_env("plumber.sharedSecret", NULL) if (!is.null(secret)){ supplied <- req$HTTP_PLUMBER_SHARED_SECRET if (!identical(supplied, secret)){ diff --git a/R/ui.R b/R/ui.R index db5701cf5..18e6c2b9d 100644 --- a/R/ui.R +++ b/R/ui.R @@ -10,13 +10,13 @@ mount_docs <- function(pr, host, port, docs_info, callback, quiet = FALSE) { } # Build api url - api_url <- getOption_env_default( + api_url <- get_option_or_env( "plumber.apiURL", urlHost( - scheme = getOption_env_default("plumber.apiScheme", "http"), - host = getOption_env_default("plumber.apiHost", host), - port = getOption_env_default("plumber.apiPort", port), - path = getOption_env_default("plumber.apiPath", ""), + scheme = get_option_or_env("plumber.apiScheme", "http"), + host = get_option_or_env("plumber.apiHost", host), + port = get_option_or_env("plumber.apiPort", port), + path = get_option_or_env("plumber.apiPath", ""), changeHostLocation = TRUE ) ) @@ -91,8 +91,8 @@ mount_openapi <- function(pr, api_url) { openapi_fun <- function(req) { # use the HTTP_REFERER so RSC can find the Docs location to ask ## (can't directly ask for 127.0.0.1) - if (is.null(getOption_env_default("plumber.apiURL")) && - is.null(getOption_env_default("plumber.apiHost"))) { + if (is.null(get_option_or_env("plumber.apiURL")) && + is.null(get_option_or_env("plumber.apiHost"))) { if (is.null(req$HTTP_REFERER)) { # Prevent leaking host and port if option is not set api_url <- character(1) @@ -256,7 +256,7 @@ registered_docs <- function() { swagger_redirects <- function() { - if (!isTRUE(getOption_env_default("plumber.legacyRedirects", TRUE))) { + if (!isTRUE(get_option_or_env("plumber.legacyRedirects", TRUE))) { return(list()) } diff --git a/man/Plumber.Rd b/man/Plumber.Rd index 16e5026f9..5090da29f 100644 --- a/man/Plumber.Rd +++ b/man/Plumber.Rd @@ -217,7 +217,7 @@ See also: \code{\link[=pr_run]{pr_run()}} \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Plumber$run( host = "127.0.0.1", - port = getOption_env_default("plumber.port", NULL), + port = get_option_or_env("plumber.port", NULL), swagger = deprecated(), debug = missing_arg(), swaggerCallback = missing_arg(), @@ -740,7 +740,7 @@ Set visual documentation to use for API See also: \code{\link[=pr_set_docs]{pr_set_docs()}}, \code{\link[=register_docs]{register_docs()}}, \code{\link[=registered_docs]{registered_docs()}} \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{Plumber$setDocs(docs = getOption_env_default("plumber.docs", TRUE), ...)}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{Plumber$setDocs(docs = get_option_or_env("plumber.docs", TRUE), ...)}\if{html}{\out{
}} } \subsection{Arguments}{ @@ -768,7 +768,7 @@ If using \code{\link[=options_plumber]{options_plumber()}}, the value must be se See also: \code{\link[=pr_set_docs_callback]{pr_set_docs_callback()}} \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Plumber$setDocsCallback( - callback = getOption_env_default("plumber.docs.callback", NULL) + callback = get_option_or_env("plumber.docs.callback", NULL) )}\if{html}{\out{
}} } diff --git a/man/options_plumber.Rd b/man/options_plumber.Rd index 96de17f12..e4c8a5aca 100644 --- a/man/options_plumber.Rd +++ b/man/options_plumber.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/options_plumber.R \name{options_plumber} \alias{options_plumber} -\alias{getOption_env_default} +\alias{get_option_or_env} \title{Plumber options} \usage{ options_plumber( @@ -22,7 +22,7 @@ options_plumber( legacyRedirects = getOption("plumber.legacyRedirects") ) -getOption_env_default(x, default = NULL) +get_option_or_env(x, default = NULL) } \arguments{ \item{...}{Ignored. Should be empty} @@ -87,3 +87,8 @@ When \code{NULL}, secret is not validated. Otherwise, Plumber compares secret wi by settings this option to \code{FALSE}. Defaults to \code{TRUE}} } } +\section{Functions}{ +\itemize{ +\item \code{get_option_or_env()}: DOCS + +}} diff --git a/man/pr_run.Rd b/man/pr_run.Rd index 679048d07..0ff65951d 100644 --- a/man/pr_run.Rd +++ b/man/pr_run.Rd @@ -7,7 +7,7 @@ pr_run( pr, host = "127.0.0.1", - port = getOption_env_default("plumber.port", NULL), + port = get_option_or_env("plumber.port", NULL), ..., debug = missing_arg(), docs = missing_arg(), diff --git a/man/pr_set_docs.Rd b/man/pr_set_docs.Rd index ca4275e00..ea47d6401 100644 --- a/man/pr_set_docs.Rd +++ b/man/pr_set_docs.Rd @@ -4,7 +4,7 @@ \alias{pr_set_docs} \title{Set the API visual documentation} \usage{ -pr_set_docs(pr, docs = getOption_env_default("plumber.docs", TRUE), ...) +pr_set_docs(pr, docs = get_option_or_env("plumber.docs", TRUE), ...) } \arguments{ \item{pr}{A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function.} diff --git a/man/pr_set_docs_callback.Rd b/man/pr_set_docs_callback.Rd index 28ee2af34..c3611e9a1 100644 --- a/man/pr_set_docs_callback.Rd +++ b/man/pr_set_docs_callback.Rd @@ -6,7 +6,7 @@ \usage{ pr_set_docs_callback( pr, - callback = getOption_env_default("plumber.docs.callback", NULL) + callback = get_option_or_env("plumber.docs.callback", NULL) ) } \arguments{ diff --git a/tests/testthat/test-options.R b/tests/testthat/test-options.R index 8d6b7c4ac..a3c3e59eb 100644 --- a/tests/testthat/test-options.R +++ b/tests/testthat/test-options.R @@ -3,18 +3,18 @@ context("Options") test_that("Options set and get", { with_options(list(plumber.port = NULL), { options_plumber(port = FALSE) - expect_false(getOption_env_default("plumber.port")) + expect_false(get_option_or_env("plumber.port")) options_plumber(port = NULL) - expect_null(getOption_env_default("plumber.port")) + expect_null(get_option_or_env("plumber.port")) }) }) test_that("Options set and get", { with_options(list(plumber.port = NULL), { Sys.setenv("PLUMBER_PORT" = FALSE) - expect_false(getOption_env_default("plumber.port")) + expect_false(get_option_or_env("plumber.port")) Sys.unsetenv("PLUMBER_PORT") - expect_null(getOption_env_default("plumber.port")) + expect_null(get_option_or_env("plumber.port")) }) }) @@ -63,7 +63,7 @@ test_that("all options used are `options_plumber()` parameters", { test_that("Legacy swagger redirect can be disabled", { with_options( list( - plumber.legacyRedirets = getOption_env_default("plumber.legacyRedirects") + plumber.legacyRedirets = get_option_or_env("plumber.legacyRedirects") ), { options_plumber(legacyRedirects = TRUE) redirects <- swagger_redirects() @@ -79,12 +79,12 @@ test_that("Legacy swagger redirect can be disabled", { test_that("docs.callback sync plumber.swagger.url", { with_options( list( - plumber.swagger.url = getOption_env_default("plumber.swagger.url"), - plumber.docs.callback = getOption_env_default("plumber.docs.callback") + plumber.swagger.url = get_option_or_env("plumber.swagger.url"), + plumber.docs.callback = get_option_or_env("plumber.docs.callback") ), { options("plumber.swagger.url" = function(api_url) {cat(api_url)}) opt <- options_plumber(docs.callback = NULL) - expect_null(getOption_env_default("plumber.swagger.url")) + expect_null(get_option_or_env("plumber.swagger.url")) expect_null(opt$plumber.docs.callback) } ) diff --git a/tests/testthat/test-plumber-run.R b/tests/testthat/test-plumber-run.R index fe2ebd05a..1efa29a37 100644 --- a/tests/testthat/test-plumber-run.R +++ b/tests/testthat/test-plumber-run.R @@ -77,8 +77,8 @@ test_that("`swaggerCallback` can be set by option after the pr is created", { with_options( list( - plumber.swagger.url = getOption_env_default("plumber.swagger.url"), - plumber.docs.callback = getOption_env_default("plumber.docs.callback") + plumber.swagger.url = get_option_or_env("plumber.swagger.url"), + plumber.docs.callback = get_option_or_env("plumber.docs.callback") ), { # set option after init From 8ecdf5071dc06a12d65f58a0ea90c2aa6e72ff1b Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 27 Nov 2023 15:41:02 -0500 Subject: [PATCH 3/4] Revert suggestion --- R/options_plumber.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/options_plumber.R b/R/options_plumber.R index 5fa25d8c4..a5f9d6be0 100644 --- a/R/options_plumber.R +++ b/R/options_plumber.R @@ -93,7 +93,7 @@ options_plumber <- function( } #' Get an option value, alternatively look in environment for value -#' @describeIn options_plumber DOCS +#' @rdname options_plumber #' @inheritParams base::options #' @export get_option_or_env <- function(x, default = NULL) { From 2aef7338f3ae370e154e5fb78e478489d12c306e Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 27 Nov 2023 15:59:47 -0500 Subject: [PATCH 4/4] Update man/options_plumber.Rd --- man/options_plumber.Rd | 5 ----- 1 file changed, 5 deletions(-) diff --git a/man/options_plumber.Rd b/man/options_plumber.Rd index e4c8a5aca..97265ec8d 100644 --- a/man/options_plumber.Rd +++ b/man/options_plumber.Rd @@ -87,8 +87,3 @@ When \code{NULL}, secret is not validated. Otherwise, Plumber compares secret wi by settings this option to \code{FALSE}. Defaults to \code{TRUE}} } } -\section{Functions}{ -\itemize{ -\item \code{get_option_or_env()}: DOCS - -}}