Skip to content
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

Add plumber_options() #555

Merged
merged 12 commits into from Jun 23, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions DESCRIPTION
Expand Up @@ -65,6 +65,7 @@ Collate:
'json.R'
'new-rstudio-project.R'
'paths.R'
'plumber-options.R'
'plumber-static.R'
'plumber-step.R'
'post-parsers.R'
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Expand Up @@ -16,6 +16,7 @@ export(include_file)
export(include_html)
export(include_md)
export(include_rmd)
export(optionsPlumber)
export(parser_json)
export(parser_multi)
export(parser_octet)
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Expand Up @@ -48,6 +48,8 @@ plumber 0.5.0

### New features

* Document plumber options. Add `optionsPlumber`. (@meztez, #555)
schloerke marked this conversation as resolved.
Show resolved Hide resolved

* Add yaml support, serializer and parser. (@meztez, #556)

* Added Swagger support for array parameters using syntax `name:[type]` and new type `list` (synonym df, data.frame). (@meztez, #532)
Expand Down
76 changes: 76 additions & 0 deletions R/plumber-options.R
@@ -0,0 +1,76 @@

#' How to use Plumber options
#'
#' @section Options:
#' There are a number of global options that affect Plumber's behavior. These can
#' be set globally with \code{\link{options}} or with \code{\link{optionsPlumber}}. Current values
#' can be retrieved with \code{\link{getOption}} or \code{\link{optionsPlumber}} without arguments.
schloerke marked this conversation as resolved.
Show resolved Hide resolved
#'
#' \describe{
#' \item{plumber.apiHost (defaults to `host` defined by `run` method, or an empty string
#' when used outside a running router)}{Host used to build UI url and server url for
#' OpenAPI specification.}
#' \item{plumber.debug (defaults to `FALSE`)}{Provides more insight into your API errors. Alternatively,
#' use parameter `debug` of plumber router `run` method}
#' \item{plumber.maxRequestSize (defaults to `0`)}{Maximum length in bytes of request body. Body larger
#' than maximum are rejected with http error 413. `0` means unlimited size.}
#' \item{plumber.postBody (defaults to `TRUE`)}{Copy post body content to `req$postBody` using system encoding.
#' This should be set to `FALSE` if you do not need it. Default is `TRUE` to preserve compatibility with
#' previous version behavior.}
#' \item{plumber.port (defaults to `NULL`)}{Port Plumber will attempt to use to start http server.
#' If the port is already in use, server will not be able to start.}
#' \item{plumber.sharedSecret (defaults to `NULL`)}{Shared secret used to filter incoming request.
#' When `NULL`, secret is not validated. Otherwise, Plumber compares secret with http header
#' `PLUMBER_SHARED_SECRET`. Failure to match results in http error 400.}
#' \item{plumber.swagger.url (defaults to `NULL`)}{A function. Called with
#' a single parameter corresponding to ui url after Plumber server is ready. This can be used
#' by RStudio to open UI when API is ran for the editor.}
#' }
#' @aliases plumber-options
"_PACKAGE"

#' Set plumber options or get non null plumber options
#' @param apiHost see \code{\link{plumber-options}}
#' @param debug see \code{\link{plumber-options}}
#' @param maxRequestSize see \code{\link{plumber-options}}
#' @param postBody see \code{\link{plumber-options}}
#' @param port see \code{\link{plumber-options}}
#' @param sharedSecret see \code{\link{plumber-options}}
#' @param swagger.url see \code{\link{plumber-options}}
#' @details
#' Sets plumber options. Call without arguments to get current
#' values.
#' @export
optionsPlumber <- function(
meztez marked this conversation as resolved.
Show resolved Hide resolved
apiHost = getOption("plumber.apiHost"),
debug = getOption("plumber.debug"),
maxRequestSize = getOption("plumber.maxRequestSize"),
postBody = getOption("plumber.postBody"),
port = getOption("plumber.port"),
sharedSecret = getOption("plumber.sharedSecret"),
swagger.url = getOption("plumber.swagger.url")
) {
if (all(
missing(apiHost),
missing(debug),
missing(maxRequestSize),
missing(postBody),
missing(port),
missing(sharedSecret),
missing(swagger.url)
)) {
options_names <- grep("^plumber", names(options()), value = TRUE)
set_options <- lapply(options_names, getOption)
names(set_options) <- options_names
return(set_options)
}
meztez marked this conversation as resolved.
Show resolved Hide resolved
options(
plumber.apiHost = apiHost,
plumber.debug = debug,
plumber.maxRequestSize = maxRequestSize,
plumber.postBody = postBody,
plumber.port = port,
plumber.sharedSecret = sharedSecret,
plumber.swagger.url = swagger.url
)
}
38 changes: 38 additions & 0 deletions man/optionsPlumber.Rd

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

67 changes: 67 additions & 0 deletions man/plumber-package.Rd

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

45 changes: 45 additions & 0 deletions tests/testthat/test-options.R
@@ -0,0 +1,45 @@
context("Options")

test_that("Options set and get", {
option_value <- getOption("plumber.postBody")
optionsPlumber(postBody = FALSE)
expect_false(getOption("plumber.postBody"))
expect_false(optionsPlumber()$plumber.postBody)
optionsPlumber(postBody = NULL)
expect_null(getOption("plumber.postBody"))
options(plumber.postBody = option_value)
})

test_that("all options used are optionsPlumber parameters", {
schloerke marked this conversation as resolved.
Show resolved Hide resolved
skip_on_cran() # only test in CI / locally

## `./R` will not exist when shiny is installed
r_folder <- "../../R"
if (
# not local structure
!dir.exists(r_folder) ||
# must contain many files, not just the three files typically found in installed folder
length(dir(r_folder)) < 10
) {
skip("Not testing locally. Skipping")
}

matches <- character()
for (r_file in dir(r_folder, full.names = T)) {
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)) {
matches <- c(matches, match)
}
}
options_used <- unique(sort(gsub("getOption|\\(|\"|,|'|\\)", "", matches)))
plumber_options_used <- grep("^plumber", options_used, value = TRUE)
### code to match formals
options_plumber_formals <- paste0("plumber.", sort(names(formals(optionsPlumber))))

expect_equal(
plumber_options_used,
options_plumber_formals
)
})