Skip to content

Commit

Permalink
Convert Ui to Docs (#658)
Browse files Browse the repository at this point in the history
Co-authored-by: Barret Schloerke <schloerke@gmail.com>
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
  • Loading branch information
3 people authored Aug 21, 2020
1 parent 33751f1 commit 743f3e0
Show file tree
Hide file tree
Showing 29 changed files with 463 additions and 462 deletions.
8 changes: 4 additions & 4 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,19 @@ export(pr_run)
export(pr_set_404)
export(pr_set_api_spec)
export(pr_set_debug)
export(pr_set_docs)
export(pr_set_docs_callback)
export(pr_set_error)
export(pr_set_parsers)
export(pr_set_serializer)
export(pr_set_ui)
export(pr_set_ui_callback)
export(pr_static)
export(random_cookie_key)
export(register_docs)
export(register_parser)
export(register_serializer)
export(register_ui)
export(registered_docs)
export(registered_parsers)
export(registered_serializers)
export(registered_uis)
export(serializer_bmp)
export(serializer_cat)
export(serializer_content_type)
Expand Down
177 changes: 91 additions & 86 deletions NEWS.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion R/globals.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.globals <- new.env()
.globals$parsers <- list()
.globals$serializers <- list()
.globals$UIs <- list()
.globals$docs <- list()
40 changes: 20 additions & 20 deletions R/plumber-options.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,53 @@
#' [options_plumber()] should not include the `plumber.` prefix.
#'
#' \describe{
#' \item{`plumber.apiURL`}{UI url and server urls for OpenAPI Specification respecting
#' pattern `scheme://host:port/path`. Other UI url options will be ignored when set.}
#' \item{`plumber.apiScheme`}{Scheme used to build UI url and server url for
#' \item{`plumber.port`}{Port Plumber will attempt to use to start http server.
#' If the port is already in use, server will not be able to start. Defaults to `NULL`}
#' \item{`plumber.docs`}{Name of the visual documentation interface to use. Defaults to `TRUE`, which will use `"swagger"`}
#' \item{`plumber.docs.callback`}{A function. Called with
#' a single parameter corresponding to the visual documentation url after Plumber server is ready. This can be used
#' by RStudio to open the docs when then API is ran from the editor. Defaults to option `NULL`}
#' \item{`plumber.apiURL`}{Server urls for OpenAPI Specification respecting
#' pattern `scheme://host:port/path`. Other `api*` options will be ignored when set.}
#' \item{`plumber.apiScheme`}{Scheme used to build OpenAPI url and server url for
#' OpenAPI Specification. Defaults to `http`, or an empty string
#' when used outside a running router}
#' \item{`plumber.apiHost`}{Host used to build UI url and server url for
#' \item{`plumber.apiHost`}{Host used to build docs url and server url for
#' OpenAPI Specification. Defaults to `host` defined by `run` method, or an empty string
#' when used outside a running router}
#' \item{`plumber.apiPort`}{Port used to build UI url and server url for
#' \item{`plumber.apiPort`}{Port used to build OpenAPI url and server url for
#' OpenAPI Specification. Defaults to `port` defined by `run` method, or an empty string
#' when used outside a running router}
#' \item{`plumber.apiPath`}{Path used to build UI url and server url for
#' \item{`plumber.apiPath`}{Path used to build OpenAPI url and server url for
#' OpenAPI Specification. Defaults to an empty string}
#' \item{`plumber.maxRequestSize`}{Maximum length in bytes of request body. Body larger
#' than maximum are rejected with http error 413. `0` means unlimited size. Defaults to `0`}
#' \item{`plumber.postBody`}{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. Defaults to `TRUE`}
#' \item{`plumber.port`}{Port Plumber will attempt to use to start http server.
#' If the port is already in use, server will not be able to start. Defaults to `NULL`}
#' \item{`plumber.sharedSecret`}{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. Defaults to `NULL`}
#' \item{`plumber.ui`}{Name of the UI interface to use. Defaults to `TRUE`}
#' \item{`plumber.ui.callback`}{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. Defaults to option `plumber.swagger.url`}
#' }
#'
#' @param apiScheme,apiHost,apiPort,apiPath,apiURL,maxRequestSize,postBody,port,sharedSecret,ui,ui.callback See details
#' @param port,docs,docs.callback,apiScheme,apiHost,apiPort,apiPath,apiURL,maxRequestSize,postBody,sharedSecret See details
#' @return
#' The complete, prior set of [options()] values.
#' If a particular parameter is not supplied, it will return the current value.
#' If no parameters are supplied, all returned values will be the current [options()] values.
#' @export
options_plumber <- function(
port = getOption("plumber.port"),
docs = getOption("plumber.docs"),
docs.callback = getOption("plumber.docs.callback"),
apiURL = getOption("plumber.apiURL"),
apiScheme = getOption("plumber.apiScheme"),
apiHost = getOption("plumber.apiHost"),
apiPort = getOption("plumber.apiPort"),
apiPath = getOption("plumber.apiPath"),
apiURL = getOption("plumber.apiURL"),
maxRequestSize = getOption("plumber.maxRequestSize"),
postBody = getOption("plumber.postBody"),
port = getOption("plumber.port"),
sharedSecret = getOption("plumber.sharedSecret"),
ui = getOption("plumber.ui"),
ui.callback = getOption("plumber.ui.callback")
sharedSecret = getOption("plumber.sharedSecret")
) {
options(
plumber.apiScheme = apiScheme,
Expand All @@ -63,7 +63,7 @@ options_plumber <- function(
plumber.postBody = postBody,
plumber.port = port,
plumber.sharedSecret = sharedSecret,
plumber.ui = ui,
plumber.ui.callback = ui.callback
plumber.docs = docs,
plumber.docs.callback = docs.callback
)
}
86 changes: 43 additions & 43 deletions R/plumber.R
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ defaultPlumberFilters <- list(
#' [pr_mount()],
#' [pr_hook()], [pr_hooks()], [pr_cookie()],
#' [pr_filter()],
#' [pr_set_api_spec()], [pr_set_ui()],
#' [pr_set_api_spec()], [pr_set_docs()],
#' [pr_set_serializer()], [pr_set_parsers()],
#' [pr_set_404()], [pr_set_error()],
#' [pr_set_debug()],
#' [pr_set_ui_callback()]
#' [pr_set_docs_callback()]
#' @include hookable.R
#' @export
Plumber <- R6Class(
Expand Down Expand Up @@ -91,9 +91,9 @@ Plumber <- R6Class(
self$setParsers(c("json", "form", "text", "octet", "multi"))
self$setErrorHandler(defaultErrorHandler())
self$set404Handler(default404Handler)
self$setUi(TRUE)
private$ui_info$has_not_been_set <- TRUE # set to know if `$setUi()` has been called before `$run()`
self$setUiCallback(getOption('plumber.ui.callback', getOption('plumber.swagger.url', NULL)))
self$setDocs(TRUE)
private$docs_info$has_not_been_set <- TRUE # set to know if `$setDocs()` has been called before `$run()`
self$setDocsCallback(getOption('plumber.docs.callback', getOption('plumber.swagger.url', NULL)))
self$setDebug(interactive())
self$setApiSpec(NULL)

Expand Down Expand Up @@ -143,8 +143,8 @@ Plumber <- R6Class(
#'
#' This value does not need to be explicitly assigned. To explicity set it, see [options_plumber()].
#' @param debug Deprecated. See `$setDebug()`
#' @param swagger Deprecated. See `$setUi(ui)` or `$setApiSpec()`
#' @param swaggerCallback Deprecated. See `$setUiCallback()`
#' @param swagger Deprecated. See `$setDocs(docs)` or `$setApiSpec()`
#' @param swaggerCallback Deprecated. See `$setDocsCallback()`
#' @importFrom lifecycle deprecated
run = function(
host = '127.0.0.1',
Expand All @@ -171,21 +171,21 @@ Plumber <- R6Class(
self$setApiSpec(swagger)
# spec is now enabled by default. Do not alter
} else {
if (isTRUE(private$ui_info$has_not_been_set)) {
if (isTRUE(private$docs_info$has_not_been_set)) {
# <= v0.4.6
lifecycle::deprecate_warn("1.0.0", "run(swagger = )", "setUi(ui = )")
self$setUi(swagger)
lifecycle::deprecate_warn("1.0.0", "run(swagger = )", "setDocs(docs = )")
self$setDocs(swagger)
} else {
# $setUi() has been called (other than during initialization).
# $setDocs() has been called (other than during initialization).
# Believe that it is the correct behavior
# Warn about updating the run method
lifecycle::deprecate_warn("1.0.0", "run(swagger = )", details = "The plumber UI has already been set. Ignoring `swagger` parameter.")
lifecycle::deprecate_warn("1.0.0", "run(swagger = )", details = "The plumber docs have already been set. Ignoring `swagger` parameter.")
}
}
}
if (lifecycle::is_present(swaggerCallback)) {
lifecycle::deprecate_warn("1.0.0", "run(swaggerCallback = )", "setUiCallback(callback = )")
self$setUiCallback(swaggerCallback)
lifecycle::deprecate_warn("1.0.0", "run(swaggerCallback = )", "setDocsCallback(callback = )")
self$setDocsCallback(swaggerCallback)
}

port <- findPort(port)
Expand All @@ -198,15 +198,15 @@ Plumber <- R6Class(
on.exit({setwd(old_wd)}, add = TRUE)
}

if (isTRUE(private$ui_info$enabled)) {
mount_ui(
if (isTRUE(private$docs_info$enabled)) {
mount_docs(
pr = self,
host = host,
port = port,
ui_info = private$ui_info,
callback = private$ui_callback
docs_info = private$docs_info,
callback = private$docs_callback
)
on.exit(unmount_ui(self, private$ui_info), add = TRUE)
on.exit(unmount_docs(self, private$docs_info), add = TRUE)
}

on.exit(private$runHooks("exit"), add = TRUE)
Expand Down Expand Up @@ -803,45 +803,45 @@ Plumber <- R6Class(
setErrorHandler = function(fun){
private$errorHandler <- fun
},
#' @description Set UI to use for API
#' @description Set visual documentation to use for API
#'
#' See also: [pr_set_ui()], [register_ui()], [registered_uis()]
#' @param ui a character value or a logical value. Defaults to `options("plumber.ui"). See [pr_set_ui()] for examples.
#' See also: [pr_set_docs()], [register_docs()], [registered_docs()]
#' @param docs a character value or a logical value. See [pr_set_docs()] for examples.
#' If using [options_plumber()], the value must be set before initializing your Plumber router.
#' @param ... Other params to be passed to `ui` functions.
setUi = function(
ui = getOption("plumber.ui", TRUE),
#' @param ... Other params to be passed to `docs` functions.
setDocs = function(
docs = getOption("plumber.docs", TRUE),
...
) {
stopifnot(length(ui) == 1)
stopifnot(is.logical(ui) || is.character(ui))
if (isTRUE(ui)) {
ui <- "swagger"
stopifnot(length(docs) == 1)
stopifnot(is.logical(docs) || is.character(docs))
if (isTRUE(docs)) {
docs <- "swagger"
}
if (is.character(ui) && is_ui_available(ui)) {
if (is.character(docs) && is_docs_available(docs)) {
enabled <- TRUE
} else {
enabled <- FALSE
ui <- "__not_enabled__"
docs <- "__not_enabled__"
}
private$ui_info <- list(
private$docs_info <- list(
enabled = enabled,
ui = ui,
docs = docs,
args = list(...)
)
},
#' @description Set UI callback to notify where the API is located.
#' @description Set a callback to notify where the API's visual documentation is located.
#'
#' When set, it will be called with a character string corresponding
#' to the API UI url. This allows RStudio to open `swagger` UI when a
#' to the API docs url. This allows RStudio to open `swagger` docs when a
#' Plumber router [pr_run()] method is executed.
#'
#' If using [options_plumber()], the value must be set before initializing your Plumber router.
#'
#' See also: [pr_set_ui_callback()]
#' @param callback a callback function for taking action on UI url. (Also accepts `NULL` values to disable the `callback`.)
setUiCallback = function(
callback = getOption('plumber.ui.callback', NULL)
#' 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)
) {
# Use callback when defined
if (!length(callback) || !is.function(callback)) {
Expand All @@ -850,7 +850,7 @@ Plumber <- R6Class(
if (length(formals(callback)) == 0) {
stop("`callback` must accept at least 1 argument. (`api_url`)")
}
private$ui_callback <- callback
private$docs_callback <- callback
},
#' @description Set debug value to include error messages
#'
Expand Down Expand Up @@ -918,7 +918,7 @@ Plumber <- R6Class(

ret <- private$api_spec_handler(ret)

# remove NA or NULL values, which UI parsers do not like
# remove NA or NULL values, which OpenAPI parsers do not like
ret <- removeNaOrNulls(ret)

ret
Expand Down Expand Up @@ -1071,8 +1071,8 @@ Plumber <- R6Class(
maxSize = NULL, # Max request size in bytes

api_spec_handler = NULL,
ui_info = NULL,
ui_callback = NULL,
docs_info = NULL,
docs_callback = NULL,
debug = NULL,

addFilterInternal = function(filter){
Expand Down
Loading

0 comments on commit 743f3e0

Please sign in to comment.