1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
#' Tools for working with plotly's REST API (v2)
#'
#' Convenience functions for working with version 2 of plotly's REST API.
#' Upload R objects to a plotly account via `api_create()` and download
#' plotly objects via `api_download_plot()`/`api_download_grid()`.
#' For anything else, use `api()`.
#'
#' @param id a filename id.
#' @param username a plotly username.
#'
#' @param x An R object to hosted on plotly's web platform.
#' Can be a plotly/ggplot2 object or a \link{data.frame}.
#' @param filename character vector naming file(s). If `x` is a plot,
#' can be a vector of length 2 naming both the plot AND the underlying grid.
#' @param fileopt character string describing whether to "overwrite" existing
#' files or ensure "new" file(s) are always created.
#' @param sharing If 'public', anyone can view this graph. It will appear in
#' your profile and can appear in search engines. You do not need to be
#' logged in to Plotly to view this chart.
#' If 'private', only you can view this plot. It will not appear in the
#' Plotly feed, your profile, or search engines. You must be logged in to
#' Plotly to view this graph. You can privately share this graph with other
#' Plotly users in your online Plotly account and they will need to be logged
#' in to view this plot.
#' If 'secret', anyone with this secret link can view this chart. It will
#' not appear in the Plotly feed, your profile, or search engines.
#' If it is embedded inside a webpage or an IPython notebook, anybody who is
#' viewing that page will be able to view the graph.
#' You do not need to be logged in to view this plot.
#'
#' @param endpoint the endpoint (i.e., location) for the request.
#' To see a list of all available endpoints, call `api()`.
#' Any relevant query parameters should be included here (see examples).
#' @param verb name of the HTTP verb to use (as in, [httr::RETRY()]).
#' @param body body of the HTTP request(as in, [httr::RETRY()]).
#' If this value is not already converted to JSON
#' (via [jsonlite::toJSON()]), it uses the internal `to_JSON()`
#' to ensure values are "automatically unboxed" (i.e., vec.
#'
#' @param ... For `api()`, these arguments are passed onto
#' [httr::RETRY()]. For `api_create()`, these arguments are
#' included in the body of the HTTP request.
#'
#' @export
#' @rdname api
#' @author Carson Sievert
#' @references \url{https://api.plot.ly/v2}
#' @seealso [signup()]
#' @examplesIf interactive() || !identical(.Platform$OS.type, "windows")
#'
#' \dontrun{
#'
#' # ------------------------------------------------------------
#' # api_create() makes it easy to upload ggplot2/plotly objects
#' # and/or data frames to your plotly account
#' # ------------------------------------------------------------
#'
#' # A data frame creates a plotly "grid". Printing one will take you
#' # to the it's web address so you can start creating!
#' (m <- api_create(mtcars))
#'
#' # A plotly/ggplot2 object create a plotly "plot".
#' p <- plot_ly(mtcars, x = ~factor(vs))
#' (r <- api_create(p))
#'
#' # api_create() returns metadata about the remote "file". Here is
#' # one way you could use that metadata to download a plot for local use:
#' fileID <- strsplit(r$file$fid, ":")[[1]]
#' layout(
#' api_download_plot(fileID[2], fileID[1]),
#' title = sprintf("Local version of <a href='%s'>this</a> plot", r$file$web_url)
#' )
#'
#' ------------------------------------------------------------
#' # The api() function provides a low-level interface for performing
#' # any action at any endpoint! It always returns a list.
#' # ------------------------------------------------------------
#'
#' # list all the endpoints
#' api()
#'
#' # search the entire platform!
#' # see https://api.plot.ly/v2/search
#' api("search?q=overdose")
#' api("search?q=plottype:pie trump fake")
#'
#' # these examples will require a user account
#' usr <- Sys.getenv("plotly_username", NA)
#' if (!is.na(usr)) {
#' # your account info https://api.plot.ly/v2/#users
#' api(sprintf("users/%s", usr))
#' # your folders/files https://api.plot.ly/v2/folders#user
#' api(sprintf("folders/home?user=%s", usr))
#' }
#'
#' # Retrieve a specific file https://api.plot.ly/v2/files#retrieve
#' api("files/cpsievert:14681")
#'
#' # change the filename https://api.plot.ly/v2/files#update
#' # (note: this won't work unless you have proper credentials to the relevant account)
#' api("files/cpsievert:14681", "PATCH", list(filename = "toy file"))
#'
#' # Copy a file https://api.plot.ly/v2/files#lookup
#' api("files/cpsievert:14681/copy", "POST")
#'
#' # Create a folder https://api.plot.ly/v2/folders#create
#' api("folders", "POST", list(path = "/starts/at/root/and/ends/here"))
#'
#' }
#'
#' @rdname api
#' @export
api_create <- function(x = last_plot(), filename = NULL,
fileopt = c("overwrite", "new"),
sharing = c("public", "private", "secret"), ...) {
fileopt <- match.arg(fileopt, c("overwrite", "new"))
sharing <- match.arg(sharing, c("public", "private", "secret"))
UseMethod("api_create")
}
#' @rdname api
#' @export
api_create.plotly <- api_create_plot
#' @rdname api
#' @export
api_create.ggplot <- api_create_plot
#' @rdname api
#' @export
api_create.data.frame <- api_create_grid
#' @rdname api
#' @export
api_download_plot <- function(id, username) {
f <- api_download_file(id, username)
api_expect_filetype(f, "plot")
as_widget(
api_download_file(id, username, "plots", "content?inline_data=true")
)
}
#' @rdname api
#' @export
api_download_grid <- function(id, username) {
f <- api_download_file(id, username)
api_expect_filetype(f, "grid")
prefix_class(
api_download_file(id, username, "grids"), "api_grid_local"
)
}
# TODO: should this be exposed to users?
api_download_file <- function(id, username, endpoint = "files", ...) {
if (missing(id)) stop("Please provide a figure id number")
if (missing(username)) username <- verify("username")
fid <- paste(username, id, sep = ":")
prefix_class(
api(file.path(endpoint, fid, ...)), "api_file"
)
}
#' @rdname api
#' @export
api <- function(endpoint = "/", verb = "GET", body = NULL, ...) {
api_check_endpoint(endpoint)
# construct the url
url <- httr::modify_url(
get_domain("api"),
scheme = "https",
# TODO: should anything else in the endpoint (besides whitespace) be escaped?
path = file.path("v2", gsub("\\s+", "+", endpoint))
)
# default to unboxing (i.e., no arrays of length 1)
if (!is.null(body) && !inherits(body, "json")) {
body <- to_JSON(body)
}
resp <- httr::RETRY(
verb = verb,
url = url,
api_headers(),
api_auth(),
body = body,
times = 5,
terminate_on = c(400, 401, 403, 404),
terminate_on_success = TRUE,
...
)
structure(process(resp), class = "api")
}
|