Skip to content
Simon Urbanek edited this page Mar 25, 2019 · 7 revisions

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 as REST calls

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 type application/x-www-form-urlencoded is parsed into a named character vector (a=b&c=d is parsed into c(a="b", c="d")), all other types are passed as the raw vector of the body content with content-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 as html.

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.

Examples of input

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()