| Title: | An API Generator for R |
|---|---|
| Description: | Gives the ability to automatically generate and serve an HTTP API from R functions using the annotations in the R documentation around your functions. |
| Authors: | Barret Schloerke [cre, aut] (ORCID: <https://orcid.org/0000-0001-9986-114X>), Jeff Allen [aut, ccp], Bruno Tremblay [ctb], Frans van Dunné [ctb], Sebastiaan Vandewoude [ctb], Posit Software, PBC [cph, fnd] (ROR: <https://ror.org/03wc8by49>) |
| Maintainer: | Barret Schloerke <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.3.3.9000 |
| Built: | 2026-05-26 06:24:38 UTC |
| Source: | https://github.com/rstudio/plumber |
This will set the appropriate fields in the Content-Disposition header value.
To make sure the attachment is used, be sure your serializer eventually calls serializer_headers
as_attachment(value, filename = NULL)as_attachment(value, filename = NULL)
value |
Response value to be saved |
filename |
File name to use when saving the attachment.
If no |
Object with class "plumber_attachment"
## Not run: # plumber.R #' @get /data #' @serializer csv function() { # will cause the file to be saved as `iris.csv`, not `data` or `data.csv` as_attachment(iris, "iris.csv") } ## End(Not run)## Not run: # plumber.R #' @get /data #' @serializer csv function() { # will cause the file to be saved as `iris.csv`, not `data` or `data.csv` as_attachment(iris, "iris.csv") } ## End(Not run)
This method allows serializers to return preexec, postexec, and aroundexec () hooks in addition to a serializer.
This is useful for graphics device serializers which need a
preexec and postexec hook to capture the graphics output.
endpoint_serializer( serializer, preexec_hook = NULL, postexec_hook = NULL, aroundexec_hook = NULL )endpoint_serializer( serializer, preexec_hook = NULL, postexec_hook = NULL, aroundexec_hook = NULL )
serializer |
Serializer method to be used. This method should already have its initialization arguments applied. |
preexec_hook |
Function to be run directly before a PlumberEndpoint calls its route method. |
postexec_hook |
Function to be run directly after a PlumberEndpoint calls its route method. |
aroundexec_hook |
Function to be run around a PlumberEndpoint call. Must handle a |
preexec and postexec hooks happened directly before and after a route is executed.
These hooks are specific to a single PlumberEndpoint's route calculation.
# The definition of `serializer_device` returns # * a `serializer_content_type` serializer # * `aroundexec` hook print(serializer_device)# The definition of `serializer_device` returns # * a `serializer_content_type` serializer # * `aroundexec` hook print(serializer_device)
This function is used when a filter is done processing a request and wishes
to pass control off to the next handler in the chain. If this is not called
by a filter, the assumption is that the filter fully handled the request
itself and no other filters or endpoints should be evaluated for this
request. forward() cannot be used within handlers to trigger the next
matching handler in the router. It only has relevance for filters.
forward()forward()
## Not run: pr() %>% pr_filter("foo", function(req, res) { print("This is filter foo") forward() }) %>% pr_run() ## End(Not run)## Not run: pr() %>% pr_filter("foo", function(req, res) { print("This is filter foo") forward() }) %>% pr_run() ## End(Not run)
Request character set
get_character_set(content_type = NULL)get_character_set(content_type = NULL)
content_type |
Request Content-Type header |
Default to UTF-8. Otherwise return charset defined in request header.
Returns the file at the given path as the response. If you want an endpoint to return a file as an attachment for user to download see as_attachment().
include_file(file, res, content_type = getContentType(tools::file_ext(file))) include_html(file, res) include_md(file, res, format = NULL) include_rmd(file, res, format = NULL)include_file(file, res, content_type = getContentType(tools::file_ext(file))) include_html(file, res) include_md(file, res, format = NULL) include_rmd(file, res, format = NULL)
file |
The path to the file to return |
res |
The response object into which we'll write |
content_type |
If provided, the given value will be sent as the
|
format |
Passed as the |
include_html will merely return the file with the proper
content_type for HTML. include_md and include_rmd will
process the given markdown file through rmarkdown::render and return
the resultant HTML as a response.
Determine if Plumber object
is_plumber(pr)is_plumber(pr)
pr |
Hopefully a |
Logical value if pr inherits from Plumber
is_plumber(Plumber$new()) # TRUE is_plumber(list()) # FALSEis_plumber(Plumber$new()) # TRUE is_plumber(list()) # FALSE
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. 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).
options_plumber( ..., port = getOption("plumber.port"), docs = getOption("plumber.docs"), docs.callback = getOption("plumber.docs.callback"), trailingSlash = getOption("plumber.trailingSlash"), methodNotAllowed = getOption("plumber.methodNotAllowed"), apiURL = getOption("plumber.apiURL"), apiScheme = getOption("plumber.apiScheme"), apiHost = getOption("plumber.apiHost"), apiPort = getOption("plumber.apiPort"), apiPath = getOption("plumber.apiPath"), maxRequestSize = getOption("plumber.maxRequestSize"), sharedSecret = getOption("plumber.sharedSecret"), legacyRedirects = getOption("plumber.legacyRedirects") ) get_option_or_env(x, default = NULL)options_plumber( ..., port = getOption("plumber.port"), docs = getOption("plumber.docs"), docs.callback = getOption("plumber.docs.callback"), trailingSlash = getOption("plumber.trailingSlash"), methodNotAllowed = getOption("plumber.methodNotAllowed"), apiURL = getOption("plumber.apiURL"), apiScheme = getOption("plumber.apiScheme"), apiHost = getOption("plumber.apiHost"), apiPort = getOption("plumber.apiPort"), apiPath = getOption("plumber.apiPath"), maxRequestSize = getOption("plumber.maxRequestSize"), sharedSecret = getOption("plumber.sharedSecret"), legacyRedirects = getOption("plumber.legacyRedirects") ) get_option_or_env(x, default = NULL)
... |
Ignored. Should be empty |
port, docs, docs.callback, trailingSlash, methodNotAllowed, apiScheme, apiHost, apiPort, apiPath, apiURL, maxRequestSize, sharedSecret, legacyRedirects
|
See details |
x |
a character string holding an option name. |
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. |
plumber.portPort 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.
plumber.docsName of the visual documentation interface to use. Defaults to TRUE, which will use "swagger".
plumber.docs.callbackA 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.
plumber.trailingSlashLogical value which allows the router to redirect any request
that has a matching route with a trailing slash. For example, if set to TRUE and the
GET route /test/ existed, then a GET request of /test?a=1 would redirect to
/test/?a=1. Defaults to FALSE. This option will default to TRUE in a future release.
plumber.methodNotAllowed
Logical value which allows the router to notify that an
unavailable method was requested, but a different request method is allowed. For example,
if set to
TRUE and the GET route /test existed, then a POST request of /test would
receive a 405 status and the allowed methods. Defaults to TRUE.
plumber.apiURLServer urls for OpenAPI Specification respecting
pattern scheme://host:port/path. Other api* options will be ignored when set.
plumber.apiSchemeScheme used to build OpenAPI url and server url for
OpenAPI Specification. Defaults to http, or an empty string
when used outside a running router.
plumber.apiHostHost 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.
plumber.apiPortPort 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.
plumber.apiPathPath used to build OpenAPI url and server url for OpenAPI Specification. Defaults to an empty string.
plumber.maxRequestSizeMaximum length in bytes of request body. Body larger
than maximum are rejected with http error 413. 0 means unlimited size. Defaults to 0.
plumber.sharedSecretShared 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.
plumber.legacyRedirectsPlumber will redirect legacy route /__swagger__/ and
/__swagger__/index.html to ../__docs__/ and ../__docs__/index.html. You can disable this
by settings this option to FALSE. Defaults to TRUE
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.
Parsers are used in Plumber to transform request body received by the API. Extra parameters may be provided to parser functions when enabling them on router. This will allow for non-default behavior.
parser_form() parser_json(...) parser_geojson(...) parser_text(parse_fn = identity) parser_yaml(...) parser_csv(...) parser_tsv(...) parser_read_file(read_fn = readLines) parser_rds(...) parser_feather(...) parser_arrow_ipc_stream(...) parser_parquet(...) parser_excel(..., sheet = NULL) parser_octet() parser_multi() parser_none()parser_form() parser_json(...) parser_geojson(...) parser_text(parse_fn = identity) parser_yaml(...) parser_csv(...) parser_tsv(...) parser_read_file(read_fn = readLines) parser_rds(...) parser_feather(...) parser_arrow_ipc_stream(...) parser_parquet(...) parser_excel(..., sheet = NULL) parser_octet() parser_multi() parser_none()
... |
parameters supplied to the appropriate internal function |
parse_fn |
function to further decode a text string into an object |
read_fn |
function used to read a the content of a file. Ex: |
sheet |
Sheet to read. Either a string (the name of a sheet), or an
integer (the position of the sheet). Defaults to the first sheet. To read all
sheets, use |
Parsers are optional. When unspecified, only default endpoint parsers are enabled.
You can use @parser NAME tag to enable parser on endpoint.
Multiple parsers can be enabled on the same endpoint using multiple @parser NAME tags.
User should be aware that rds parsing should only be done from a
trusted source. Do not accept rds files blindly.
See registered_parsers() for a list of registered parsers names.
parser_form(): Form query string parser
parser_json(): JSON parser. See jsonlite::parse_json() for more details. (Defaults to using simplifyVectors = TRUE)
parser_geojson(): GeoJSON parser. See geojsonsf::geojson_sf() for more details.
parser_text(): Helper parser to parse plain text
parser_yaml(): YAML parser. See yaml::yaml.load() for more details.
parser_csv(): CSV parser. See readr::read_csv() for more details.
parser_tsv(): TSV parser. See readr::read_tsv() for more details.
parser_read_file(): Helper parser that writes the binary body to a file and reads it back again using read_fn.
This parser should be used when reading from a file is required.
parser_rds(): RDS parser. See readRDS() for more details.
parser_feather(): feather parser. See arrow::read_feather() for more details.
parser_arrow_ipc_stream(): Arrow IPC parser. See arrow::read_ipc_stream() for more details.
parser_parquet(): parquet parser. See arrow::read_parquet() for more details.
parser_excel(): excel parser. See readxl::read_excel() for more details. (Defaults to reading in the first worksheet only, use @parser excel list(sheet=NA) to read in all worksheets.)
parser_octet(): Octet stream parser. Returns the raw content.
parser_multi(): Multi part parser. This parser will then parse each individual body with its respective parser. When this parser is used, req$body will contain the updated output from webutils::parse_multipart() by adding the parsed output to each part. Each part may contain detailed information, such as name (required), content_type, content_disposition, filename, (raw, original) value, and parsed (parsed value). When performing Plumber route argument matching, each multipart part will match its name to the parsed content.
parser_none(): No parser. Will not process the postBody.
## Not run: # Overwrite `text/json` parsing behavior to not allow JSON vectors to be simplified #* @parser json list(simplifyVector = FALSE) # Activate `rds` parser in a multipart request #* @parser multi #* @parser rds pr <- Plumber$new() pr$handle("GET", "/upload", function(rds) {rds}, parsers = c("multi", "rds")) ## End(Not run)## Not run: # Overwrite `text/json` parsing behavior to not allow JSON vectors to be simplified #* @parser json list(simplifyVector = FALSE) # Activate `rds` parser in a multipart request #* @parser multi #* @parser rds pr <- Plumber$new() pr$handle("GET", "/upload", function(rds) {rds}, parsers = c("multi", "rds")) ## End(Not run)
Process a Plumber API
plumb(file = NULL, dir = ".")plumb(file = NULL, dir = ".")
file |
The file to parse as the plumber router definition. |
dir |
The directory containing the |
API routers are the core request handler in plumber. A router is responsible for taking an incoming request, submitting it through the appropriate filters and eventually to a corresponding endpoint, if one is found.
See the Programmatic Usage article for additional details on the methods available on this object.
So that packages can ship multiple plumber routers, users should store their Plumber APIs
in the inst subfolder plumber (./inst/plumber/API_1/plumber.R).
plumb_api(package = NULL, name = NULL, edit = FALSE) available_apis(package = NULL)plumb_api(package = NULL, name = NULL, edit = FALSE) available_apis(package = NULL)
package |
Package to inspect |
name |
Name of the package folder to |
edit |
Whether or not to open the API source code for viewing / editing |
To view all available Plumber APIs across all packages, please call available_apis().
A package value may be provided to only display a particular package's Plumber APIs.
A Plumber object. If either package or name is null, the appropriate available_apis() will be returned.
plumb_api(): plumb()s a package's Plumber API. Returns a Plumber router object
available_apis(): Displays all available package Plumber APIs. Returns a data.frame of package, name, and source_directory information.
Package Plumber Router
Package Plumber Router
Routers are the core request handler in plumber. A router is responsible for taking an incoming request, submitting it through the appropriate filters and eventually to a corresponding endpoint, if one is found.
See the Programmatic Usage article for additional details on the methods available on this object.
plumber::Hookable -> Plumber
flagsFor internal use only
endpointsPlumber router endpoints read-only
filtersPlumber router filters read-only
mountsPlumber router mounts read-only
environmentPlumber router environment read-only
routesPlumber router routes read-only
new()
Create a new Plumber router
Plumber$new(file = NULL, filters = defaultPlumberFilters, envir)
filepath to file to plumb
filtersa list of Plumber filters
enviran environment to be used as the enclosure for the routers execution
A new Plumber router
run()
Start a server using Plumber object.
See also: pr_run()
Plumber$run(
host = "127.0.0.1",
port = get_option_or_env("plumber.port", NULL),
swagger = deprecated(),
debug = missing_arg(),
swaggerCallback = missing_arg(),
...,
docs = missing_arg(),
quiet = FALSE
)hosta string that is a valid IPv4 or IPv6 address that is owned by this server, which the application will listen on. "0.0.0.0" represents all IPv4 addresses and "::/0" represents all IPv6 addresses.
porta number or integer that indicates the server port that should be listened on. Note that on most Unix-like systems including Linux and Mac OS X, port numbers smaller than 1025 require root privileges.
This value does not need to be explicitly assigned. To explicitly set it, see options_plumber().
swaggerDeprecated. Please use docs instead. See $setDocs(docs) or $setApiSpec() for more customization.
debugIf TRUE, it will provide more insight into your API errors. Using this value will only last for the duration of the run. If a $setDebug() has not been called, debug will default to FALSE at $run() time. See $setDebug() for more details.
swaggerCallbackAn optional single-argument function that is
called back with the URL to an OpenAPI user interface when one becomes
ready. If missing, defaults to information previously set with $setDocsCallback().
This value will only be used while running the router.
...Should be empty.
docsVisual documentation value to use while running the API.
This value will only be used while running the router.
If missing, defaults to information previously set with setDocs().
For more customization, see $setDocs() or pr_set_docs() for examples.
quietIf TRUE, don't print routine startup messages.
mount()
Mount a Plumber router
Plumber routers can be “nested” by mounting one into another
using the mount() method. This allows you to compartmentalize your API
by paths which is a great technique for decomposing large APIs into smaller files.
See also: pr_mount()
Plumber$mount(path, router)
patha character string. Where to mount router.
routera Plumber router. Router to be mounted.
\dontrun{
root <- pr()
users <- Plumber$new("users.R")
root$mount("/users", users)
products <- Plumber$new("products.R")
root$mount("/products", products)
}
unmount()
Unmount a Plumber router
Plumber$unmount(path)
patha character string. Where to unmount router.
registerHook()
Register a hook
Plumber routers support the notion of "hooks" that can be registered to execute some code at a particular point in the lifecycle of a request. Plumber routers currently support four hooks:
preroute(data, req, res)
postroute(data, req, res, value)
preserialize(data, req, res, value)
postserialize(data, req, res, value)
In all of the above you have access to a disposable environment in the data
parameter that is created as a temporary data store for each request. Hooks
can store temporary data in these hooks that can be reused by other hooks
processing this same request.
One feature when defining hooks in Plumber routers is the ability to modify
the returned value. The convention for such hooks is: any function that accepts
a parameter named value is expected to return the new value. This could
be an unmodified version of the value that was passed in, or it could be a
mutated value. But in either case, if your hook accepts a parameter
named value, whatever your hook returns will be used as the new value
for the response.
You can add hooks using the registerHook method, or you can add multiple
hooks at once using the registerHooks method which takes a name list in
which the names are the names of the hooks, and the values are the
handlers themselves.
See also: pr_hook(), pr_hooks()
Plumber$registerHook(
stage = c("preroute", "postroute", "preserialize", "postserialize", "exit"),
handler
)stagea character string. Point in the lifecycle of a request.
handlera hook function.
\dontrun{
pr <- pr()
pr$registerHook("preroute", function(req){
cat("Routing a request for", req$PATH_INFO, "...\n")
})
pr$registerHooks(list(
preserialize=function(req, value){
print("About to serialize this value:")
print(value)
# Must return the value since we took one in. Here we're not choosing
# to mutate it, but we could.
value
},
postserialize=function(res){
print("We serialized the value as:")
print(res$body)
}
))
pr$handle("GET", "/", function(){ 123 })
}
handle()
Define endpoints
The “handler” functions that you define in these handle calls are identical to the code you would have defined in your plumber.R file if you were using annotations to define your API. The handle() method takes additional arguments that allow you to control nuanced behavior of the endpoint like which filter it might preempt or which serializer it should use.
See also: pr_handle(), pr_get(), pr_post(), pr_put(), pr_delete()
Plumber$handle( methods, path, handler, preempt, serializer, parsers, endpoint, ... )
methodsa character string. http method.
patha character string. Api endpoints
handlera handler function.
preempta preempt function.
serializera serializer function.
parsersa named list of parsers.
endpointa PlumberEndpoint object.
...additional arguments for PlumberEndpoint new method (namely lines, params, comments, responses and tags. Excludes envir).
\dontrun{
pr <- pr()
pr$handle("GET", "/", function(){
"<html><h1>Programmatic Plumber!</h1></html>"
}, serializer=plumber::serializer_html())
}
removeHandle()
Remove endpoints
Plumber$removeHandle(methods, path, preempt = NULL)
methodsa character string. http method.
patha character string. Api endpoints
preempta preempt function.
print()
Print representation of plumber router.
Plumber$print(prefix = "", topLevel = TRUE, ...)
prefixa character string. Prefix to append to representation.
topLevela logical value. When method executed on top level
router, set to TRUE.
...additional arguments for recursive calls
A terminal friendly representation of a plumber router.
serve()
Serve a request
Plumber$serve(req, res)
reqrequest object
resresponse object
route()
Route a request
Plumber$route(req, res)
reqrequest object
resresponse object
call()
httpuv interface call function. (Required for httpuv)
Plumber$call(req)
reqrequest object
onHeaders()
httpuv interface onHeaders function. (Required for httpuv)
Plumber$onHeaders(req)
reqrequest object
onWSOpen()
httpuv interface onWSOpen function. (Required for httpuv)
Plumber$onWSOpen(ws)
wsWebSocket object
setSerializer()
Sets the default serializer of the router.
See also: pr_set_serializer()
Plumber$setSerializer(serializer)
serializera serializer function
\dontrun{
pr <- pr()
pr$setSerializer(serializer_unboxed_json())
}
setParsers()
Sets the default parsers of the router. Initialized to c("json", "form", "text", "octet", "multi")
Plumber$setParsers(parsers)
parsersCan be one of:
A NULL value
A character vector of parser names
A named list() whose keys are parser names names and values are arguments to be applied with do.call()
A TRUE value, which will default to combining all parsers. This is great for seeing what is possible, but not great for security purposes
If the parser name "all" is found in any character value or list name, all remaining parsers will be added.
When using a list, parser information already defined will maintain their existing argument values. All remaining parsers will use their default arguments.
Example:
# provide a character string
parsers = "json"
# provide a named list with no arguments
parsers = list(json = list())
# provide a named list with arguments; include `rds`
parsers = list(json = list(simplifyVector = FALSE), rds = list())
# default plumber parsers
parsers = c("json", "form", "text", "octet", "multi")
set404Handler()
Sets the handler that gets called if an incoming request can’t be served by any filter, endpoint, or sub-router.
See also: pr_set_404()
Plumber$set404Handler(fun)
funa handler function.
\dontrun{
pr <- pr()
pr$set404Handler(function(req, res) {cat(req$PATH_INFO)})
}
setErrorHandler()
Sets the error handler which gets invoked if any filter or endpoint generates an error.
See also: pr_set_404()
Plumber$setErrorHandler(fun)
funa handler function.
\dontrun{
pr <- pr()
pr$setErrorHandler(function(req, res, err) {
message("Found error: ")
str(err)
})
}
setDocs()
Set visual documentation to use for API
See also: pr_set_docs(), register_docs(), registered_docs()
Plumber$setDocs(docs = get_option_or_env("plumber.docs", TRUE), ...)docsa 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.
...Arguments for the visual documentation. See each visual documentation package for further details.
setDocsCallback()
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 docs url. This allows RStudio to locate visual documentation.
If using options_plumber(), the value must be set before initializing your Plumber router.
See also: pr_set_docs_callback()
Plumber$setDocsCallback(
callback = get_option_or_env("plumber.docs.callback", NULL)
)callbacka callback function for taking action on the docs url. (Also accepts NULL values to disable the callback.)
setDebug()
Set debug value to include error messages.
See also: $getDebug() and pr_set_debug()
Plumber$setDebug(debug = FALSE)
debugTRUE provides more insight into your API errors.
getDebug()
Retrieve the debug value. If it has never been set, it will return FALSE.
See also: $getDebug() and pr_set_debug()
Plumber$getDebug()
filter()
Add a filter to plumber router
See also: pr_filter()
Plumber$filter(name, expr, serializer)
namea character string. Name of filter
expran expr that resolve to a filter function or a filter function
serializera serializer function
setApiSpec()
Allows to modify router autogenerated OpenAPI Specification
Note, the returned value will be sent through serializer_unboxed_json() which will turn all length 1 vectors into atomic values.
To force a vector to serialize to an array of size 1, be sure to call as.list() on your value. list() objects are always serialized to an array value.
See also: pr_set_api_spec()
Plumber$setApiSpec(api = NULL)
apiThis can be
an OpenAPI Specification formatted list object
a function that accepts the OpenAPI Specification autogenerated by plumber and returns a OpenAPI Specification formatted list object.
a path to an OpenAPI Specification
The value returned will not be validated for OAS compatibility.
getApiSpec()
Retrieve OpenAPI file
Plumber$getApiSpec()
addEndpoint()
addEndpoint has been deprecated in v0.4.0 and will be removed in a coming release. Please use handle() instead.
Plumber$addEndpoint( verbs, path, expr, serializer, processors, preempt = NULL, params = NULL, comments )
verbsverbs
pathpath
exprexpr
serializerserializer
processorsprocessors
preemptpreempt
paramsparams
commentscomments
addAssets()
addAssets has been deprecated in v0.4.0 and will be removed in a coming release. Please use mount and PlumberStatic$new() instead.
Plumber$addAssets(dir, path = "/public", options = list())
dirdir
pathpath
optionsoptions
addFilter()
$addFilter() has been deprecated in v0.4.0 and will be removed in a coming release. Please use $filter() instead.
Plumber$addFilter(name, expr, serializer, processors)
namename
exprexpr
serializerserializer
processorsprocessors
addGlobalProcessor()
$addGlobalProcessor() has been deprecated in v0.4.0 and will be removed in a coming release. Please use $registerHook(s) instead.
Plumber$addGlobalProcessor(proc)
procproc
openAPIFile()
Deprecated. Retrieve OpenAPI file
Plumber$openAPIFile()
swaggerFile()
Deprecated. Retrieve OpenAPI file
Plumber$swaggerFile()
clone()
The objects of this class are cloneable with this method.
Plumber$clone(deep = FALSE)
deepWhether to make a deep clone.
pr(),
pr_run(),
pr_get(), pr_post(),
pr_mount(),
pr_hook(), pr_hooks(), pr_cookie(),
pr_filter(),
pr_set_api_spec(), pr_set_docs(),
pr_set_serializer(), pr_set_parsers(),
pr_set_404(), pr_set_error(),
pr_set_debug(),
pr_set_docs_callback()
## ------------------------------------------------ ## Method `Plumber$mount` ## ------------------------------------------------ ## Not run: root <- pr() users <- Plumber$new("users.R") root$mount("/users", users) products <- Plumber$new("products.R") root$mount("/products", products) ## End(Not run) ## ------------------------------------------------ ## Method `Plumber$registerHook` ## ------------------------------------------------ ## Not run: pr <- pr() pr$registerHook("preroute", function(req){ cat("Routing a request for", req$PATH_INFO, "...\n") }) pr$registerHooks(list( preserialize=function(req, value){ print("About to serialize this value:") print(value) # Must return the value since we took one in. Here we're not choosing # to mutate it, but we could. value }, postserialize=function(res){ print("We serialized the value as:") print(res$body) } )) pr$handle("GET", "/", function(){ 123 }) ## End(Not run) ## ------------------------------------------------ ## Method `Plumber$handle` ## ------------------------------------------------ ## Not run: pr <- pr() pr$handle("GET", "/", function(){ "<html><h1>Programmatic Plumber!</h1></html>" }, serializer=plumber::serializer_html()) ## End(Not run) ## ------------------------------------------------ ## Method `Plumber$setSerializer` ## ------------------------------------------------ ## Not run: pr <- pr() pr$setSerializer(serializer_unboxed_json()) ## End(Not run) ## ------------------------------------------------ ## Method `Plumber$set404Handler` ## ------------------------------------------------ ## Not run: pr <- pr() pr$set404Handler(function(req, res) {cat(req$PATH_INFO)}) ## End(Not run) ## ------------------------------------------------ ## Method `Plumber$setErrorHandler` ## ------------------------------------------------ ## Not run: pr <- pr() pr$setErrorHandler(function(req, res, err) { message("Found error: ") str(err) }) ## End(Not run)## ------------------------------------------------ ## Method `Plumber$mount` ## ------------------------------------------------ ## Not run: root <- pr() users <- Plumber$new("users.R") root$mount("/users", users) products <- Plumber$new("products.R") root$mount("/products", products) ## End(Not run) ## ------------------------------------------------ ## Method `Plumber$registerHook` ## ------------------------------------------------ ## Not run: pr <- pr() pr$registerHook("preroute", function(req){ cat("Routing a request for", req$PATH_INFO, "...\n") }) pr$registerHooks(list( preserialize=function(req, value){ print("About to serialize this value:") print(value) # Must return the value since we took one in. Here we're not choosing # to mutate it, but we could. value }, postserialize=function(res){ print("We serialized the value as:") print(res$body) } )) pr$handle("GET", "/", function(){ 123 }) ## End(Not run) ## ------------------------------------------------ ## Method `Plumber$handle` ## ------------------------------------------------ ## Not run: pr <- pr() pr$handle("GET", "/", function(){ "<html><h1>Programmatic Plumber!</h1></html>" }, serializer=plumber::serializer_html()) ## End(Not run) ## ------------------------------------------------ ## Method `Plumber$setSerializer` ## ------------------------------------------------ ## Not run: pr <- pr() pr$setSerializer(serializer_unboxed_json()) ## End(Not run) ## ------------------------------------------------ ## Method `Plumber$set404Handler` ## ------------------------------------------------ ## Not run: pr <- pr() pr$set404Handler(function(req, res) {cat(req$PATH_INFO)}) ## End(Not run) ## ------------------------------------------------ ## Method `Plumber$setErrorHandler` ## ------------------------------------------------ ## Not run: pr <- pr() pr$setErrorHandler(function(req, res, err) { message("Found error: ") str(err) }) ## End(Not run)
Plumber Endpoint
Plumber Endpoint
Defines a terminal handler in a Plumber router.
Parameters values are obtained from parsing blocks of lines in a plumber file. They can also be provided manually for historical reasons.
plumber::Hookable -> plumber::PlumberStep -> PlumberEndpoint
verbsa character vector. http methods. For historical reasons we have to accept multiple verbs for a single path. Now it's simpler to just parse each separate verb/path into its own endpoint, so we just do that.
patha character string. endpoint path
commentsendpoint comments
descriptionendpoint description
responsesendpoint responses
paramsendpoint parameters
tagsendpoint tags
parsersstep allowed parsers
getTypedParams()
retrieve endpoint typed parameters
PlumberEndpoint$getTypedParams()
canServe()
ability to serve request
PlumberEndpoint$canServe(req)
reqa request object
a logical. TRUE when endpoint can serve request.
matchesPath()
determines if route matches requested path
PlumberEndpoint$matchesPath(path)
patha url path
a logical. TRUE when endpoint matches the requested path.
new()
Create a new PlumberEndpoint object
PlumberEndpoint$new( verbs, path, expr, envir, serializer, parsers, lines, params, comments, description, responses, tags, srcref )
verbsEndpoint verb Ex: "GET", "POST"
pathEndpoint path. Ex: "/index.html", "/foo/bar/baz"
exprEndpoint function or expression that evaluates to a function.
envirEndpoint environment
serializerEndpoint serializer. Ex: serializer_json()
parsersCan be one of:
A NULL value
A character vector of parser names
A named list() whose keys are parser names names and values are arguments to be applied with do.call()
A TRUE value, which will default to combining all parsers. This is great for seeing what is possible, but not great for security purposes
If the parser name "all" is found in any character value or list name, all remaining parsers will be added.
When using a list, parser information already defined will maintain their existing argument values. All remaining parsers will use their default arguments.
Example:
# provide a character string
parsers = "json"
# provide a named list with no arguments
parsers = list(json = list())
# provide a named list with arguments; include `rds`
parsers = list(json = list(simplifyVector = FALSE), rds = list())
# default plumber parsers
parsers = c("json", "form", "text", "octet", "multi")
linesEndpoint block
paramsEndpoint params
comments, description, responses, tagsValues to be used within the OpenAPI Spec
srcrefsrcref attribute from block
A new PlumberEndpoint object
getPathParams()
retrieve endpoint path parameters
PlumberEndpoint$getPathParams(path)
pathendpoint path
getFunc()
retrieve endpoint function
PlumberEndpoint$getFunc()
getFuncParams()
retrieve endpoint expression parameters
PlumberEndpoint$getFuncParams()
getEndpointParams()
retrieve endpoint defined parameters
PlumberEndpoint$getEndpointParams()
setPath()
Updates $path with a sanitized path and updates the internal path meta-data
PlumberEndpoint$setPath(path)
pathPath to set $path. If missing a beginning slash, one will be added.
clone()
The objects of this class are cloneable with this method.
PlumberEndpoint$clone(deep = FALSE)
deepWhether to make a deep clone.
Static file router
Static file router
Creates a router that is backed by a directory of files on disk.
plumber::Hookable -> plumber::Plumber -> PlumberStatic
plumber::Hookable$registerHooks()plumber::Plumber$addAssets()plumber::Plumber$addEndpoint()plumber::Plumber$addFilter()plumber::Plumber$addGlobalProcessor()plumber::Plumber$call()plumber::Plumber$filter()plumber::Plumber$getApiSpec()plumber::Plumber$getDebug()plumber::Plumber$handle()plumber::Plumber$mount()plumber::Plumber$onHeaders()plumber::Plumber$onWSOpen()plumber::Plumber$openAPIFile()plumber::Plumber$registerHook()plumber::Plumber$removeHandle()plumber::Plumber$route()plumber::Plumber$run()plumber::Plumber$serve()plumber::Plumber$set404Handler()plumber::Plumber$setApiSpec()plumber::Plumber$setDebug()plumber::Plumber$setDocs()plumber::Plumber$setDocsCallback()plumber::Plumber$setErrorHandler()plumber::Plumber$setParsers()plumber::Plumber$setSerializer()plumber::Plumber$swaggerFile()plumber::Plumber$unmount()new()
Create a new PlumberStatic router
PlumberStatic$new(direc, options)
direca path to an asset directory.
optionsoptions to be evaluated in the PlumberStatic router environment
A new PlumberStatic router
print()
Print representation of PlumberStatic() router.
PlumberStatic$print(prefix = "", topLevel = TRUE, ...)
prefixa character string. Prefix to append to representation.
topLevela logical value. When method executed on top level
router, set to TRUE.
...additional arguments for recursive calls
A terminal friendly representation of a PlumberStatic() router.
clone()
The objects of this class are cloneable with this method.
PlumberStatic$clone(deep = FALSE)
deepWhether to make a deep clone.
an object representing a step in the lifecycle of the treatment of a request by a plumber router.
plumber::Hookable -> PlumberStep
srcreffrom step block
lineslines from step block
serializerstep serializer function
new()
Create a new PlumberStep() object
PlumberStep$new(expr, envir, lines, serializer, srcref)
exprstep expr
envirstep environment
linesstep block
serializerstep serializer
srcrefsrcref attribute from block
A new PlumberStep object
exec()
step execution function
PlumberStep$exec(req, res)
req, resRequest and response objects created by a Plumber request
registerHook()
step hook registration method
PlumberStep$registerHook(
stage = c("preexec", "postexec", "aroundexec"),
handler
)stagea character string.
handlera step handler function.
clone()
The objects of this class are cloneable with this method.
PlumberStep$clone(deep = FALSE)
deepWhether to make a deep clone.
Create a new Plumber router
pr( file = NULL, filters = defaultPlumberFilters, envir = new.env(parent = .GlobalEnv) )pr( file = NULL, filters = defaultPlumberFilters, envir = new.env(parent = .GlobalEnv) )
file |
Path to file to plumb |
filters |
A list of Plumber filters |
envir |
An environment to be used as the enclosure for the routers execution |
A new Plumber router
## Not run: pr() %>% pr_run() ## End(Not run)## Not run: pr() %>% pr_run() ## End(Not run)
plumber uses the crypto R package sodium, to encrypt/decrypt
req$session information for each server request.
pr_cookie( pr, key, name = "plumber", expiration = FALSE, http = TRUE, secure = FALSE, same_site = FALSE, path = NULL )pr_cookie( pr, key, name = "plumber", expiration = FALSE, http = TRUE, secure = FALSE, same_site = FALSE, path = NULL )
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
key |
The secret key to use. This must be consistent across all R sessions
where you want to save/restore encrypted cookies. It should be produced using
|
name |
The name of the cookie in the user's browser. |
expiration |
A number representing the number of seconds into the future
before the cookie expires or a |
http |
Boolean that adds the |
secure |
Boolean that adds the |
same_site |
A character specifying the SameSite policy to attach to the cookie.
If specified, one of the following values should be given: "Strict", "Lax", or "None".
If "None" is specified, then the |
path |
The URI path that the cookie will be available in future requests.
Defaults to the request URI. Set to |
The cookie's secret encryption key value must be consistent to maintain
req$session information between server restarts.
While it is very quick to get started with user session cookies using
plumber, please exercise precaution when storing secure key information.
If a malicious person were to gain access to the secret key, they would
be able to eavesdrop on all req$session information and/or tamper with
req$session information being processed.
Please:
Do NOT store keys in source control.
Do NOT store keys on disk with permissions that allow it to be accessed by everyone.
Do NOT store keys in databases which can be queried by everyone.
Instead, please:
Use a key management system, such as 'keyring' (preferred)
Store the secret in a file on disk with appropriately secure permissions,
such as "user read only" (Sys.chmod("myfile.txt", mode = "0600")),
to prevent others from reading it.
Examples of both of these solutions are done in the Examples section.
'sodium': R bindings to 'libsodium'
'libsodium': A Modern and Easy-to-Use Crypto Library
'keyring': Access the system credential store from R
Set-Cookie flags: Descriptions of different flags for Set-Cookie
Cross-site scripting: A security exploit which allows an attacker to inject into a website malicious client-side code
## Not run: ## Set secret key using `keyring` (preferred method) keyring::key_set_with_value("plumber_api", password = plumber::random_cookie_key()) pr() %>% pr_cookie( keyring::key_get("plumber_api"), name = "counter" ) %>% pr_get("/sessionCounter", function(req) { count <- 0 if (!is.null(req$session$counter)){ count <- as.numeric(req$session$counter) } req$session$counter <- count + 1 return(paste0("This is visit #", count)) }) %>% pr_run() #### -------------------------------- ### ## Save key to a local file pswd_file <- "normal_file.txt" cat(plumber::random_cookie_key(), file = pswd_file) # Make file read-only Sys.chmod(pswd_file, mode = "0600") pr() %>% pr_cookie( readLines(pswd_file, warn = FALSE), name = "counter" ) %>% pr_get("/sessionCounter", function(req) { count <- 0 if (!is.null(req$session$counter)){ count <- as.numeric(req$session$counter) } req$session$counter <- count + 1 return(paste0("This is visit #", count)) }) %>% pr_run() ## End(Not run)## Not run: ## Set secret key using `keyring` (preferred method) keyring::key_set_with_value("plumber_api", password = plumber::random_cookie_key()) pr() %>% pr_cookie( keyring::key_get("plumber_api"), name = "counter" ) %>% pr_get("/sessionCounter", function(req) { count <- 0 if (!is.null(req$session$counter)){ count <- as.numeric(req$session$counter) } req$session$counter <- count + 1 return(paste0("This is visit #", count)) }) %>% pr_run() #### -------------------------------- ### ## Save key to a local file pswd_file <- "normal_file.txt" cat(plumber::random_cookie_key(), file = pswd_file) # Make file read-only Sys.chmod(pswd_file, mode = "0600") pr() %>% pr_cookie( readLines(pswd_file, warn = FALSE), name = "counter" ) %>% pr_get("/sessionCounter", function(req) { count <- 0 if (!is.null(req$session$counter)){ count <- as.numeric(req$session$counter) } req$session$counter <- count + 1 return(paste0("This is visit #", count)) }) %>% pr_run() ## End(Not run)
Filters can be used to modify an incoming request, return an error, or return a response prior to the request reaching an endpoint.
pr_filter(pr, name, expr, serializer)pr_filter(pr, name, expr, serializer)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
name |
A character string. Name of filter |
expr |
An expr that resolve to a filter function or a filter function |
serializer |
A serializer function |
The Plumber router with the defined filter added
## Not run: pr() %>% pr_filter("foo", function(req, res) { print("This is filter foo") forward() }) %>% pr_get("/hi", function() "Hello") %>% pr_run() ## End(Not run)## Not run: pr() %>% pr_filter("foo", function(req, res) { print("This is filter foo") forward() }) %>% pr_get("/hi", function() "Hello") %>% pr_run() ## End(Not run)
This collection of functions creates handlers for a Plumber router.
pr_handle(pr, methods, path, handler, preempt, serializer, endpoint, ...) pr_get(pr, path, handler, preempt, serializer, endpoint, ...) pr_post(pr, path, handler, preempt, serializer, endpoint, ...) pr_put(pr, path, handler, preempt, serializer, endpoint, ...) pr_delete(pr, path, handler, preempt, serializer, endpoint, ...) pr_head(pr, path, handler, preempt, serializer, endpoint, ...)pr_handle(pr, methods, path, handler, preempt, serializer, endpoint, ...) pr_get(pr, path, handler, preempt, serializer, endpoint, ...) pr_post(pr, path, handler, preempt, serializer, endpoint, ...) pr_put(pr, path, handler, preempt, serializer, endpoint, ...) pr_delete(pr, path, handler, preempt, serializer, endpoint, ...) pr_head(pr, path, handler, preempt, serializer, endpoint, ...)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
methods |
Character vector of HTTP methods |
path |
The endpoint path |
handler |
A handler function |
preempt |
A preempt function |
serializer |
A Plumber serializer |
endpoint |
A |
... |
Additional arguments for |
The generic pr_handle() creates a handle for the given method(s). Specific
functions are implemented for the following HTTP methods:
GET
POST
PUT
DELETE
HEAD
Each function mutates the Plumber router in place and returns
the updated router.
A Plumber router with the handler added
## Not run: pr() %>% pr_handle("GET", "/hi", function() "Hello World") %>% pr_run() pr() %>% pr_handle(c("GET", "POST"), "/hi", function() "Hello World") %>% pr_run() pr() %>% pr_get("/hi", function() "Hello World") %>% pr_post("/echo", function(req, res) { if (is.null(req$body)) return("No input") list( input = req$body ) }) %>% pr_run() ## End(Not run)## Not run: pr() %>% pr_handle("GET", "/hi", function() "Hello World") %>% pr_run() pr() %>% pr_handle(c("GET", "POST"), "/hi", function() "Hello World") %>% pr_run() pr() %>% pr_get("/hi", function() "Hello World") %>% pr_post("/echo", function(req, res) { if (is.null(req$body)) return("No input") list( input = req$body ) }) %>% pr_run() ## End(Not run)
Plumber routers support the notion of "hooks" that can be registered to execute some code at a particular point in the lifecycle of a request. Plumber routers currently support four hooks:
preroute(data, req, res)
postroute(data, req, res, value)
preserialize(data, req, res, value)
postserialize(data, req, res, value)
In all of the above you have access to a disposable environment in the data
parameter that is created as a temporary data store for each request. Hooks
can store temporary data in these hooks that can be reused by other hooks
processing this same request.
pr_hook(pr, stage, handler) pr_hooks(pr, handlers)pr_hook(pr, stage, handler) pr_hooks(pr, handlers)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
stage |
A character string. Point in the lifecycle of a request. |
handler |
A hook function. |
handlers |
A named list of hook handlers |
One feature when defining hooks in Plumber routers is the ability to modify
the returned value. The convention for such hooks is: any function that accepts
a parameter named value is expected to return the new value. This could
be an unmodified version of the value that was passed in, or it could be a
mutated value. But in either case, if your hook accepts a parameter
named value, whatever your hook returns will be used as the new value
for the response.
You can add hooks using the pr_hook, or you can add multiple
hooks at once using pr_hooks, which takes a named list in
which the names are the names of the hooks, and the values are the
handlers themselves.
A Plumber router with the defined hook(s) added
## Not run: pr() %>% pr_hook("preroute", function(req){ cat("Routing a request for", req$PATH_INFO, "...\n") }) %>% pr_hooks(list( preserialize = function(req, value){ print("About to serialize this value:") print(value) # Must return the value since we took one in. Here we're not choosing # to mutate it, but we could. value }, postserialize = function(res){ print("We serialized the value as:") print(res$body) } )) %>% pr_handle("GET", "/", function(){ 123 }) %>% pr_run() ## End(Not run)## Not run: pr() %>% pr_hook("preroute", function(req){ cat("Routing a request for", req$PATH_INFO, "...\n") }) %>% pr_hooks(list( preserialize = function(req, value){ print("About to serialize this value:") print(value) # Must return the value since we took one in. Here we're not choosing # to mutate it, but we could. value }, postserialize = function(res){ print("We serialized the value as:") print(res$body) } )) %>% pr_handle("GET", "/", function(){ 123 }) %>% pr_run() ## End(Not run)
Plumber routers can be “nested” by mounting one into another
using the mount() method. This allows you to compartmentalize your API
by paths which is a great technique for decomposing large APIs into smaller
files. This function mutates the Plumber router (pr()) in place and
returns the updated router.
pr_mount(pr, path, router)pr_mount(pr, path, router)
pr |
The host Plumber router. |
path |
A character string. Where to mount router. |
router |
A Plumber router. Router to be mounted. |
A Plumber router with the supplied router mounted
## Not run: pr1 <- pr() %>% pr_get("/hello", function() "Hello") pr() %>% pr_get("/goodbye", function() "Goodbye") %>% pr_mount("/hi", pr1) %>% pr_run() ## End(Not run)## Not run: pr1 <- pr() %>% pr_get("/hello", function() "Hello") pr() %>% pr_get("/goodbye", function() "Goodbye") %>% pr_mount("/hi", pr1) %>% pr_run() ## End(Not run)
plumber objectport does not need to be explicitly assigned.
pr_run( pr, host = "127.0.0.1", port = get_option_or_env("plumber.port", NULL), ..., debug = missing_arg(), docs = missing_arg(), swaggerCallback = missing_arg(), quiet = FALSE )pr_run( pr, host = "127.0.0.1", port = get_option_or_env("plumber.port", NULL), ..., debug = missing_arg(), docs = missing_arg(), swaggerCallback = missing_arg(), quiet = FALSE )
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
host |
A string that is a valid IPv4 or IPv6 address that is owned by this server, which the application will listen on. "0.0.0.0" represents all IPv4 addresses and "::/0" represents all IPv6 addresses. |
port |
A number or integer that indicates the server port that should be listened on. Note that on most Unix-like systems including Linux and Mac OS X, port numbers smaller than 1025 require root privileges. |
... |
Should be empty. |
debug |
If |
docs |
Visual documentation value to use while running the API.
This value will only be used while running the router.
If missing, defaults to information previously set with |
swaggerCallback |
An optional single-argument function that is called
back with the URL to an OpenAPI user interface when one becomes ready. If
missing, defaults to information set with |
quiet |
If |
## Not run: pr() %>% pr_run() pr() %>% pr_run( # manually set port port = 5762, # turn off visual documentation docs = FALSE, # do not display startup messages quiet = TRUE ) ## End(Not run)## Not run: pr() %>% pr_run() pr() %>% pr_run( # manually set port port = 5762, # turn off visual documentation docs = FALSE, # do not display startup messages quiet = TRUE ) ## End(Not run)
This function allows a custom error message to be returned when a request cannot be served by an existing endpoint or filter.
pr_set_404(pr, fun)pr_set_404(pr, fun)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
fun |
A handler function |
The Plumber router with a modified 404 handler
## Not run: handler_404 <- function(req, res) { res$status <- 404 res$body <- "Oops" } pr() %>% pr_get("/hi", function() "Hello") %>% pr_set_404(handler_404) %>% pr_run() ## End(Not run)## Not run: handler_404 <- function(req, res) { res$status <- 404 res$body <- "Oops" } pr() %>% pr_get("/hi", function() "Hello") %>% pr_set_404(handler_404) %>% pr_run() ## End(Not run)
Allows to modify OpenAPI Specification autogenerated by plumber.
pr_set_api_spec(pr, api)pr_set_api_spec(pr, api)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
api |
This can be
The value returned will not be validated for OAS compatibility. |
Note, the returned value will be sent through serializer_unboxed_json() which will turn all length 1 vectors into atomic values.
To force a vector to serialize to an array of size 1, be sure to call as.list() on your value. list() objects are always serialized to an array value.
The Plumber router with the new OpenAPI Specification object or function.
## Not run: # Set the API Spec to a function to use the auto-generated OAS object pr() %>% pr_set_api_spec(function(spec) { spec$info$title <- Sys.time() spec }) %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() # Set the API Spec using an object pr() %>% pr_set_api_spec(my_custom_object) %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() ## End(Not run)## Not run: # Set the API Spec to a function to use the auto-generated OAS object pr() %>% pr_set_api_spec(function(spec) { spec$info$title <- Sys.time() spec }) %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() # Set the API Spec using an object pr() %>% pr_set_api_spec(my_custom_object) %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() ## End(Not run)
By default, error messages from your plumber routes are hidden, but can be
turned on by setting the debug value to TRUE using this setter.
pr_set_debug(pr, debug = FALSE)pr_set_debug(pr, debug = FALSE)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
debug |
|
The Plumber router with the new debug setting.
## Not run: # Will contain the original error message pr() %>% pr_set_debug(TRUE) %>% pr_get("/boom", function() stop("boom")) %>% pr_run() # Will NOT contain an error message pr() %>% pr_set_debug(FALSE) %>% pr_get("/boom", function() stop("boom")) %>% pr_run() ## End(Not run) # Setting within a plumber file #* @plumber function(pr) { pr %>% pr_set_debug(TRUE) }## Not run: # Will contain the original error message pr() %>% pr_set_debug(TRUE) %>% pr_get("/boom", function() stop("boom")) %>% pr_run() # Will NOT contain an error message pr() %>% pr_set_debug(FALSE) %>% pr_get("/boom", function() stop("boom")) %>% pr_run() ## End(Not run) # Setting within a plumber file #* @plumber function(pr) { pr %>% pr_set_debug(TRUE) }
docs should be either a logical or a character value matching a registered visual documentation.
Multiple handles will be added to Plumber object. OpenAPI json
file will be served on paths /openapi.json. Documentation
will be served on paths /__docs__/index.html and /__docs__/.
pr_set_docs(pr, docs = get_option_or_env("plumber.docs", TRUE), ...)pr_set_docs(pr, docs = get_option_or_env("plumber.docs", TRUE), ...)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
docs |
a character value or a logical value.
If using |
... |
Arguments for the visual documentation. See each visual documentation package for further details. |
The Plumber router with the new docs settings.
## Not run: ## View API using Swagger UI # Official Website: https://swagger.io/tools/swagger-ui/ # install.packages("swagger") if (require(swagger)) { pr() %>% pr_set_docs("swagger") %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() } ## View API using Redoc # Official Website: https://github.com/Redocly/redoc if (require(redoc)) { pr() %>% pr_set_docs("redoc") %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() } ## View API using RapiDoc # Official Website: https://github.com/mrin9/RapiDoc if (require(rapidoc)) { pr() %>% pr_set_docs("rapidoc") %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() } ## Disable the OpenAPI Spec UI pr() %>% pr_set_docs(FALSE) %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() ## End(Not run)## Not run: ## View API using Swagger UI # Official Website: https://swagger.io/tools/swagger-ui/ # install.packages("swagger") if (require(swagger)) { pr() %>% pr_set_docs("swagger") %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() } ## View API using Redoc # Official Website: https://github.com/Redocly/redoc if (require(redoc)) { pr() %>% pr_set_docs("redoc") %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() } ## View API using RapiDoc # Official Website: https://github.com/mrin9/RapiDoc if (require(rapidoc)) { pr() %>% pr_set_docs("rapidoc") %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() } ## Disable the OpenAPI Spec UI pr() %>% pr_set_docs(FALSE) %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() ## End(Not run)
callback to tell where the API visual documentation is locatedWhen set, it will be called with a character string corresponding to the API visual documentation url. This allows RStudio to locate visual documentation.
pr_set_docs_callback( pr, callback = get_option_or_env("plumber.docs.callback", NULL) )pr_set_docs_callback( pr, callback = get_option_or_env("plumber.docs.callback", NULL) )
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
callback |
a callback function for taking action on the docs url. |
If using options_plumber(), the value must be set before initializing your Plumber router.
The Plumber router with the new docs callback setting.
## Not run: pr() %>% pr_set_docs_callback(function(url) { message("API location: ", url) }) %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() ## End(Not run)## Not run: pr() %>% pr_set_docs_callback(function(url) { message("API location: ", url) }) %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() ## End(Not run)
Set the error handler that is invoked if any filter or endpoint generates an error
pr_set_error(pr, fun)pr_set_error(pr, fun)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
fun |
An error handler function. This should accept |
The Plumber router with a modified error handler
## Not run: handler_error <- function(req, res, err){ res$status <- 500 list(error = "Custom Error Message") } pr() %>% pr_get("/error", function() log("a")) %>% pr_set_error(handler_error) %>% pr_run() ## End(Not run)## Not run: handler_error <- function(req, res, err){ res$status <- 500 list(error = "Custom Error Message") } pr() %>% pr_get("/error", function() log("a")) %>% pr_set_error(handler_error) %>% pr_run() ## End(Not run)
By default, Plumber will parse JSON, text, query strings, octet streams, and multipart bodies. This function updates the default parsers for any endpoint that does not define their own parsers.
pr_set_parsers(pr, parsers)pr_set_parsers(pr, parsers)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
parsers |
Can be one of:
If the parser name Example: # provide a character string
parsers = "json"
# provide a named list with no arguments
parsers = list(json = list())
# provide a named list with arguments; include `rds`
parsers = list(json = list(simplifyVector = FALSE), rds = list())
# default plumber parsers
parsers = c("json", "form", "text", "octet", "multi")
|
Note: The default set of parsers will be completely replaced if any value is supplied. Be sure to include all of your parsers that you would like to include.
Use registered_parsers() to get a list of available parser names.
The Plumber router with the new default PlumberEndpoint parsers
By default, Plumber serializes responses to JSON. This function updates the
default serializer to the function supplied via serializer
pr_set_serializer(pr, serializer)pr_set_serializer(pr, serializer)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
serializer |
A serializer function |
The Plumber router with the new default serializer
plumber objectAdd a static route to the plumber object
pr_static(pr, path, direc)pr_static(pr, path, direc)
pr |
A Plumber API. Note: The supplied Plumber API object will also be updated in place as well as returned by the function. |
path |
The mounted path location of the static folder |
direc |
The local folder to be served statically |
## Not run: pr() %>% pr_static("/path", "./my_folder/location") %>% pr_run() ## End(Not run)## Not run: pr() %>% pr_static("/path", "./my_folder/location") %>% pr_run() ## End(Not run)
Uses a cryptographically secure pseudorandom number generator from sodium::helpers() to generate a 64 digit hexadecimal string. 'sodium' wraps around 'libsodium'.
random_cookie_key()random_cookie_key()
Please see session_cookie for more information on how to save the generated key.
A 64 digit hexadecimal string to be used as a key for cookie encryption.
register_docs() is used by other packages like swagger, rapidoc, and redoc.
When you load these packages, it calls register_docs() to provide a user
interface that can interpret your plumber OpenAPI Specifications.
register_docs(name, index, static = NULL) registered_docs()register_docs(name, index, static = NULL) registered_docs()
name |
Name of the visual documentation |
index |
A function that returns the HTML content of the landing page of the documentation.
Parameters (besides |
static |
A function that returns the path to the static assets (images, javascript, css, fonts) the Docs will use. |
## Not run: # Example from the `swagger` R package register_docs( name = "swagger", index = function(version = "3", ...) { swagger::swagger_spec( api_path = paste0( "window.location.origin + ", "window.location.pathname.replace(", "/\\(__docs__\\\\/|__docs__\\\\/index.html\\)$/, \"\"", ") + ", "\"openapi.json\"" ), version = version ) }, static = function(version = "3", ...) { swagger::swagger_path(version) } ) # When setting the docs, `index` and `static` function arguments can be supplied # * via `pr_set_docs()` # * or through URL query string variables pr() %>% # Set default argument `version = "3"` for the swagger `index` and `static` functions pr_set_docs("swagger", version = "3") %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() ## End(Not run)## Not run: # Example from the `swagger` R package register_docs( name = "swagger", index = function(version = "3", ...) { swagger::swagger_spec( api_path = paste0( "window.location.origin + ", "window.location.pathname.replace(", "/\\(__docs__\\\\/|__docs__\\\\/index.html\\)$/, \"\"", ") + ", "\"openapi.json\"" ), version = version ) }, static = function(version = "3", ...) { swagger::swagger_path(version) } ) # When setting the docs, `index` and `static` function arguments can be supplied # * via `pr_set_docs()` # * or through URL query string variables pr() %>% # Set default argument `version = "3"` for the swagger `index` and `static` functions pr_set_docs("swagger", version = "3") %>% pr_get("/plus/<a:int>/<b:int>", function(a, b) { a + b }) %>% pr_run() ## End(Not run)
A parser is responsible for decoding the raw body content of a request into
a list of arguments that can be mapped to endpoint function arguments.
For instance, parser_json() parse content-type application/json.
register_parser(alias, parser, fixed = NULL, regex = NULL, verbose = TRUE) registered_parsers()register_parser(alias, parser, fixed = NULL, regex = NULL, verbose = TRUE) registered_parsers()
alias |
An alias to map parser from the |
parser |
The parser function to be added. This build the parser function. See Details for more information. |
fixed |
A character vector of fixed string to be matched against a request |
regex |
A character vector of regex string to be matched against a request |
verbose |
Logical value which determines if a warning should be displayed when alias in map are overwritten. |
When parser is evaluated, it should return a parser function.
Parser matching is done first by content-type header matching with fixed then by using
regular expressions with regex. Note that plumber strips ; charset* from content-type header before matching.
Plumber will try to use parser_json() (if available) when no content-type header is found and
the request body starts with { or [.
Functions signature should include value, ... and
possibly content_type, filename. Other parameters may be provided
if you want to use the headers from webutils::parse_multipart().
Parser function structure is something like below.
function(parser_arguments_here) {
# return a function to parse a raw value
function(value, ...) {
# do something with raw value
}
}
registered_parsers(): Return all registered parsers
# `content-type` header is mostly used to look up charset and adjust encoding parser_dcf <- function(...) { function(value, content_type = "text/x-dcf", ...) { charset <- get_character_set(content_type) value <- rawToChar(value) Encoding(value) <- charset read.dcf(value, ...) } } # Could also leverage existing parsers parser_dcf <- function(...) { parser_read_file(function(tmpfile) { read.dcf(tmpfile, ...) }) } # Register the newly created parser ## Not run: register_parser("dcf", parser_dcf, fixed = "text/x-dcf")# `content-type` header is mostly used to look up charset and adjust encoding parser_dcf <- function(...) { function(value, content_type = "text/x-dcf", ...) { charset <- get_character_set(content_type) value <- rawToChar(value) Encoding(value) <- charset read.dcf(value, ...) } } # Could also leverage existing parsers parser_dcf <- function(...) { parser_read_file(function(tmpfile) { read.dcf(tmpfile, ...) }) } # Register the newly created parser ## Not run: register_parser("dcf", parser_dcf, fixed = "text/x-dcf")
A serializer is responsible for translating a generated R value into output
that a remote user can understand. For instance, the serializer_json
serializes R objects into JSON before returning them to the user. The list of
available serializers in plumber is global.
register_serializer(name, serializer, verbose = TRUE) registered_serializers()register_serializer(name, serializer, verbose = TRUE) registered_serializers()
name |
The name of the serializer (character string) |
serializer |
The serializer function to be added.
This function should accept arguments that can be supplied when |
verbose |
Logical value which determines if a message should be printed when overwriting serializers |
There are three main building-block serializers:
serializer_headers: the base building-block serializer that is required to have as_attachment() work
serializer_content_type(): for setting the content type. (Calls serializer_headers())
serializer_device(): add endpoint hooks to turn a graphics device on and off in addition to setting the content type. (Uses serializer_content_type())
register_serializer(): Register a serializer with a name
registered_serializers(): Return a list of all registered serializers
# `serializer_json()` calls `serializer_content_type()` and supplies a serialization function print(serializer_json) # serializer_content_type() calls `serializer_headers()` and supplies a serialization function print(serializer_content_type)# `serializer_json()` calls `serializer_content_type()` and supplies a serialization function print(serializer_json) # serializer_content_type() calls `serializer_headers()` and supplies a serialization function print(serializer_content_type)
Serializers are used in Plumber to transform the R object produced by a filter/endpoint into an HTTP response that can be returned to the client. See here for more details on Plumber serializers and how to customize their behavior.
serializer_headers(headers = list(), serialize_fn = identity) serializer_content_type(type, serialize_fn = identity) serializer_octet(..., type = "application/octet-stream") serializer_csv(..., type = "text/csv; charset=UTF-8") serializer_tsv(..., type = "text/tab-separated-values; charset=UTF-8") serializer_html(type = "text/html; charset=UTF-8") serializer_json(..., type = "application/json") serializer_unboxed_json(auto_unbox = TRUE, ..., type = "application/json") serializer_geojson(..., type = "application/geo+json") serializer_rds(version = "2", ascii = FALSE, ..., type = "application/rds") serializer_feather(type = "application/vnd.apache.arrow.file") serializer_arrow_ipc_stream(type = "application/vnd.apache.arrow.stream") serializer_parquet(type = "application/vnd.apache.parquet") serializer_excel( ..., type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) serializer_yaml(..., type = "text/x-yaml; charset=UTF-8") serializer_text( ..., serialize_fn = as.character, type = "text/plain; charset=UTF-8" ) serializer_format(..., type = "text/plain; charset=UTF-8") serializer_print(..., type = "text/plain; charset=UTF-8") serializer_cat(..., type = "text/plain; charset=UTF-8") serializer_write_file(type, write_fn, fileext = NULL) serializer_htmlwidget(..., type = "text/html; charset=UTF-8") serializer_device(type, dev_on, dev_off = grDevices::dev.off) serializer_jpeg(..., type = "image/jpeg") serializer_png(..., type = "image/png") serializer_svg(..., type = "image/svg+xml") serializer_bmp(..., type = "image/bmp") serializer_tiff(..., type = "image/tiff") serializer_pdf(..., type = "application/pdf") serializer_agg_jpeg(..., type = "image/jpeg") serializer_agg_png(..., type = "image/png") serializer_agg_tiff(..., type = "image/tiff") serializer_svglite(..., type = "image/svg+xml")serializer_headers(headers = list(), serialize_fn = identity) serializer_content_type(type, serialize_fn = identity) serializer_octet(..., type = "application/octet-stream") serializer_csv(..., type = "text/csv; charset=UTF-8") serializer_tsv(..., type = "text/tab-separated-values; charset=UTF-8") serializer_html(type = "text/html; charset=UTF-8") serializer_json(..., type = "application/json") serializer_unboxed_json(auto_unbox = TRUE, ..., type = "application/json") serializer_geojson(..., type = "application/geo+json") serializer_rds(version = "2", ascii = FALSE, ..., type = "application/rds") serializer_feather(type = "application/vnd.apache.arrow.file") serializer_arrow_ipc_stream(type = "application/vnd.apache.arrow.stream") serializer_parquet(type = "application/vnd.apache.parquet") serializer_excel( ..., type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) serializer_yaml(..., type = "text/x-yaml; charset=UTF-8") serializer_text( ..., serialize_fn = as.character, type = "text/plain; charset=UTF-8" ) serializer_format(..., type = "text/plain; charset=UTF-8") serializer_print(..., type = "text/plain; charset=UTF-8") serializer_cat(..., type = "text/plain; charset=UTF-8") serializer_write_file(type, write_fn, fileext = NULL) serializer_htmlwidget(..., type = "text/html; charset=UTF-8") serializer_device(type, dev_on, dev_off = grDevices::dev.off) serializer_jpeg(..., type = "image/jpeg") serializer_png(..., type = "image/png") serializer_svg(..., type = "image/svg+xml") serializer_bmp(..., type = "image/bmp") serializer_tiff(..., type = "image/tiff") serializer_pdf(..., type = "application/pdf") serializer_agg_jpeg(..., type = "image/jpeg") serializer_agg_png(..., type = "image/png") serializer_agg_tiff(..., type = "image/tiff") serializer_svglite(..., type = "image/svg+xml")
headers |
|
serialize_fn |
Function to serialize the data. The result object will be converted to a character string. Ex: |
type |
The value to provide for the |
... |
extra arguments supplied to respective internal serialization function. |
auto_unbox |
automatically |
version |
the workspace format version to use. |
ascii |
a logical. If |
write_fn |
Function that should write serialized content to the temp file provided. |
fileext |
A non-empty character vector giving the file extension. This value will try to be inferred from the content type provided. |
dev_on |
Function to turn on a graphics device.
The graphics device |
dev_off |
Function to turn off the graphics device. Defaults to |
serializer_headers(): Add a static list of headers to each return value. Will add Content-Disposition header if a value is the result of as_attachment().
serializer_content_type(): Adds a Content-Type header to the response object
serializer_octet(): Octet serializer. If content is received that does
not have a "raw" type, then an error will be thrown.
serializer_csv(): CSV serializer. See also: readr::format_csv()
serializer_tsv(): TSV serializer. See also: readr::format_tsv()
serializer_html(): HTML serializer
serializer_json(): JSON serializer. See also: jsonlite::toJSON()
serializer_unboxed_json(): JSON serializer with auto_unbox defaulting to TRUE. See also: jsonlite::toJSON()
serializer_geojson(): GeoJSON serializer. See also geojsonsf::sf_geojson() and [geojsonsf::sfc_geojson()].
serializer_rds(): RDS serializer. See also: base::serialize()
serializer_feather(): feather serializer. See also: arrow::write_feather()
serializer_arrow_ipc_stream(): Arrow IPC serializer. See also: arrow::write_ipc_stream()
serializer_parquet(): parquet serializer. See also: arrow::write_parquet()
serializer_excel(): excel serializer. See also: writexl::write_xlsx()
serializer_yaml(): YAML serializer. See also: yaml::as.yaml()
serializer_text(): Text serializer. See also: as.character()
serializer_format(): Text serializer. See also: format()
serializer_print(): Text serializer. Captures the output of print()
serializer_cat(): Text serializer. Captures the output of cat()
serializer_write_file(): Write output to a temp file whose contents are read back as a serialized response. serializer_write_file() creates (and cleans up) a temp file, calls the serializer (which should write to the temp file), and then reads the contents back as the serialized value. If the content type starts with "text", the return result will be read into a character string, otherwise the result will be returned as a raw vector.
serializer_htmlwidget(): htmlwidget serializer. See also: htmlwidgets::saveWidget()
serializer_device(): Helper method to create graphics device serializers, such as serializer_png(). See also: endpoint_serializer()
serializer_jpeg(): JPEG image serializer. See also: grDevices::jpeg()
serializer_png(): PNG image serializer. See also: grDevices::png()
serializer_svg(): SVG image serializer. See also: grDevices::svg()
serializer_bmp(): BMP image serializer. See also: grDevices::bmp()
serializer_tiff(): TIFF image serializer. See also: grDevices::tiff()
serializer_pdf(): PDF image serializer. See also: grDevices::pdf()
serializer_agg_jpeg(): JPEG image serializer using ragg. See also: ragg::agg_jpeg()
serializer_agg_png(): PNG image serializer using ragg. See also: ragg::agg_png()
serializer_agg_tiff(): TIFF image serializer using ragg. See also: ragg::agg_tiff()
serializer_svglite(): SVG image serializer using svglite. See also: svglite::svglite()
plumber uses the crypto R package sodium, to encrypt/decrypt
req$session information for each server request.
session_cookie( key, name = "plumber", expiration = FALSE, http = TRUE, secure = FALSE, same_site = FALSE, path = NULL )session_cookie( key, name = "plumber", expiration = FALSE, http = TRUE, secure = FALSE, same_site = FALSE, path = NULL )
key |
The secret key to use. This must be consistent across all R sessions
where you want to save/restore encrypted cookies. It should be produced using
|
name |
The name of the cookie in the user's browser. |
expiration |
A number representing the number of seconds into the future
before the cookie expires or a |
http |
Boolean that adds the |
secure |
Boolean that adds the |
same_site |
A character specifying the SameSite policy to attach to the cookie.
If specified, one of the following values should be given: "Strict", "Lax", or "None".
If "None" is specified, then the |
path |
The URI path that the cookie will be available in future requests.
Defaults to the request URI. Set to |
The cookie's secret encryption key value must be consistent to maintain
req$session information between server restarts.
While it is very quick to get started with user session cookies using
plumber, please exercise precaution when storing secure key information.
If a malicious person were to gain access to the secret key, they would
be able to eavesdrop on all req$session information and/or tamper with
req$session information being processed.
Please:
Do NOT store keys in source control.
Do NOT store keys on disk with permissions that allow it to be accessed by everyone.
Do NOT store keys in databases which can be queried by everyone.
Instead, please:
Use a key management system, such as 'keyring' (preferred)
Store the secret in a file on disk with appropriately secure permissions,
such as "user read only" (Sys.chmod("myfile.txt", mode = "0600")),
to prevent others from reading it.
Examples of both of these solutions are done in the Examples section.
'sodium': R bindings to 'libsodium'
'libsodium': A Modern and Easy-to-Use Crypto Library
'keyring': Access the system credential store from R
Set-Cookie flags: Descriptions of different flags for Set-Cookie
Cross-site scripting: A security exploit which allows an attacker to inject into a website malicious client-side code
## Not run: ## Set secret key using `keyring` (preferred method) keyring::key_set_with_value("plumber_api", plumber::random_cookie_key()) # Load a plumber API plumb_api("plumber", "01-append") %>% # Add cookie support via `keyring` pr_cookie( keyring::key_get("plumber_api") ) %>% pr_run() #### -------------------------------- ### ## Save key to a local file pswd_file <- "normal_file.txt" cat(plumber::random_cookie_key(), file = pswd_file) # Make file read-only Sys.chmod(pswd_file, mode = "0600") # Load a plumber API plumb_api("plumber", "01-append") %>% # Add cookie support and retrieve secret key from file pr_cookie( readLines(pswd_file, warn = FALSE) ) %>% pr_run() ## End(Not run)## Not run: ## Set secret key using `keyring` (preferred method) keyring::key_set_with_value("plumber_api", plumber::random_cookie_key()) # Load a plumber API plumb_api("plumber", "01-append") %>% # Add cookie support via `keyring` pr_cookie( keyring::key_get("plumber_api") ) %>% pr_run() #### -------------------------------- ### ## Save key to a local file pswd_file <- "normal_file.txt" cat(plumber::random_cookie_key(), file = pswd_file) # Make file read-only Sys.chmod(pswd_file, mode = "0600") # Load a plumber API plumb_api("plumber", "01-append") %>% # Add cookie support and retrieve secret key from file pr_cookie( readLines(pswd_file, warn = FALSE) ) %>% pr_run() ## End(Not run)
Validate an OpenAPI Spec using @redocly/cli.
validate_api_spec( pr, ..., ruleset = c("minimal", "recommended", "recommended-strict"), verbose = TRUE )validate_api_spec( pr, ..., ruleset = c("minimal", "recommended", "recommended-strict"), verbose = TRUE )
pr |
A Plumber API |
... |
Ignored |
ruleset |
Character that determines the ruleset to use for validation. Can be one of "minimal", "recommended",
or "recommended-strict". Defaults to "minimal". See |
verbose |
Logical that determines if a "is valid" statement is displayed. Defaults to |
If any warning or error is presented, an error will be thrown.
This function is and may be altered, changed, or removed in the future.
## Not run: pr <- plumb_api("plumber", "01-append") validate_api_spec(pr) ## End(Not run)## Not run: pr <- plumb_api("plumber", "01-append") validate_api_spec(pr) ## End(Not run)