-
Notifications
You must be signed in to change notification settings - Fork 142
notebook.R API
The notebook.R
entry point serves two purposes:
- serve notebooks as "scripts" processing REST API
- serve static assets from notebooks
The general URL for REST calls is one of
/notebook.R/<notebook-id>[/<version>][?<query-string>]
/notebook.R/<user>/<notebook-name>[/.self<path-info>][?<query-string>]
for static asset access it is
/notebook.R/<notebook-id>[/<version>]/<asset-name>
/notebook.R/<user>/<notebook-name>/<asset-name>
Where <notebook>
is a 20-character lowercase hex id of the notebook and <version>
is a 40-character hex id of the version.
Notebooks called via notebook.R
are evaluated (R cells only!) and the result has to be a function. That function is then called with the following arguments:
mandatory:
-
notebook
argument is set to the notebook ID - the full path piece of the url is passed as
.url
(sorry for the misnomer) -
.headers
character vector containing the request headers (since RCloud 1.6)
optional:
-
.version
is passed if a particular notebook version was requested - query parameters are parsed into arguments [e.g.
?a=b
is passed as(a="b")
] - body is passed as the
.body
argument if present. Content of typeapplication/x-www-form-urlencoded
is parsed into a named character vector (a=b&c=d
is parsed intoc(a="b", c="d")
), all other types are passed as the raw vector of the body content withcontent-type
attribute storing the content type from the header. - cookies are parsed into the
.cookies
argument - dynamic paths beyond
.self
are passed as a.path.info
argument (character vector)
The result of the notebook is whatever object has been returned by rcloud.call.notebook()
, i.e. the result of the last R cell. It can be one of:
- a
WebResult
object (see WebResult() documentation) - any other object that will be coerced to WebResult via
as.WebResult()
(e.g.,WebPlot
). The default handling for objects is to turn them into character vectors and pass ashtml
.
NOTE: currently, if the notebook does not return a function, it can be of the form list(payload[, content-type[, headers[, status code]]])
which will be passed through (see R HTTP API documentation). All other cases will lead to a 500 error.
Probably the most trivial notebook to show what is passed into the function:
function(...) WebResult("html", paste(capture.output(str(list(...))),
collapse="\n"), "text/plain")
Most simple GET:
$ curl https://rcloud.research.att.com/notebook.R/0a10de2ba3685cf64ea0
List of 3
$ .cookies: list()
$ .url : chr "/notebook.R/0a10de2ba3685cf64ea0"
$ notebook: chr "0a10de2ba3685cf64ea0"
GET with query:
$ curl https://rcloud.research.att.com/notebook.R/0a10de2ba3685cf64ea0?a=b
List of 4
$ a : chr "b"
$ .cookies: list()
$ .url : chr "/notebook.R/0a10de2ba3685cf64ea0"
$ notebook: chr "0a10de2ba3685cf64ea0"
GET with path info:
$ curl https://rcloud.research.att.com/notebook.R/0a10de2ba3685cf64ea0/.self/foo/bar
List of 4
$ .cookies : list()
$ .url : chr "/notebook.R/0a10de2ba3685cf64ea0/.self/foo/bar"
$ notebook : chr "0a10de2ba3685cf64ea0"
$ .path.info: chr [1:3] ".self" "foo" "bar"
POST with form:
$ curl -d a=b https://rcloud.research.att.com/notebook.R/0a10de2ba3685cf64ea0
List of 4
$ .cookies: list()
$ .body : Named chr "b"
..- attr(*, "names")= chr "a"
$ .url : chr "/notebook.R/0a10de2ba3685cf64ea0"
$ notebook: chr "0a10de2ba3685cf64ea0"
POST with form and query:
$ curl -d a=b https://rcloud.research.att.com/notebook.R/0a10de2ba3685cf64ea0?c=d
List of 5
$ c : chr "d"
$ .cookies: list()
$ .body : Named chr "b"
..- attr(*, "names")= chr "a"
$ .url : chr "/notebook.R/0a10de2ba3685cf64ea0"
$ notebook: chr "0a10de2ba3685cf64ea0"
POST with binary multiform:
$ curl -F file=foobar.html https://rcloud.research.att.com/notebook.R/0a10de2ba3685cf64ea0
List of 4
$ .cookies: list()
$ .body : atomic [1:150] 2d 2d 2d 2d ...
..- attr(*, "content-type")= chr "multipart/form-data; boundary=------------------------4997f0fbeec056f5"
$ .url : chr "/notebook.R/0a10de2ba3685cf64ea0"
$ notebook: chr "0a10de2ba3685cf64ea0"
FWIW there are tools to parse the last case on the R side - see FastRWeb::parse.multipart()