12 Tutorial API

12.1 Overview

The Tutorial API provides an interface for driving automated interactions with the RStudio IDE. The Tutorial API assumes that RStudio is hosted within an <iframe> with the hosting page content surrounding it (e.g. in a sidebar).

The hosting <iframe> must be connected to the DOM and have non-zero dimensions (including not having the display: none style) when the IDE is loaded into it.

The API supports a variety of interactions with the IDE including typing console input, opening source files, opening projects, creating projects, showing help topics, and executing arbitrary R code.

This document describes the basic workings of the Tutorial API, and related settings. A simple example page is provided to demonstrate invoking the APIs.

The Tutorial API files are installed with RStudio Server in:

/usr/lib/rstudio-server/extras/tutorial

  • demo.htm is an example host page
  • rstudio.js is used by a hosting page to interact with the Tutorial API; always use the version of rstudio.js that came with the installed version of RStudio Server Pro and ensure it is cache-busted to prevent web browsers from using an older cached version (one option would be to rename it and reference it via that new name, e.g. rstudio001.js)

Important: These instructions, and the example page itself, assume the following regarding the domains utilized:

If the IDE is being served from a different domain than http://localhost:8787 edit the demo.htm file and change all instances of http://localhost:8787 to the actual domain where the IDE is available.

12.2 Configuration

This section describes how to configure the example page, shown below. The upper-region has controls for experimenting with the Tutorial API calls, and the lower region is an <iframe> hosting RStudio Server Pro.

Example Page

Example Page

12.2.1 Allow IFrame

For security reasons, RStudio Server will not load inside a browser frame (such as an IFrame) by default. You can modify this behavior by using the www-frame-origin option. See Frame Origin for full details.

To enable the Tutorial API example page to host RStudio Server on a non-production localhost server, do the following:

/etc/rstudio/rserver.conf

www-frame-origin=http://localhost:8080

Note: if the www-frame-origin option is set to same or any instead of a URI, you must add the following setting with the actual URI:

/etc/rstudio/rsession.conf

tutorial-api-client-origin=http://localhost:8080

12.2.2 Enable API Calls from Host Page

To enable calling the Tutorial APIs from the hosting page:

/etc/rstudio/rsession.conf

tutorial-api-enabled=1

12.2.3 Enable Callbacks from RStudio to Host Page

RStudio may optionally notify the hosting page of certain events using the JavaScript PostMessage mechanism.

The receiver is responsible for parsing, interpreting, and reacting to the value of the callbacks. Any JavaScript running in the context of the IDE IFrame could do an arbitrary SendMessage to the parent (in addition to those being generated by the RStudio IDE JavaScript). The host page should ensure the response string is valid JSON, and follows one of the patterns described in Tutorial API Callbacks.

To enable callbacks:

/etc/rstudio/rsession.conf

tutorial-api-parent-notify-enabled=1

12.2.4 Disable RStudio Server Pro Home Page

The Tutorial API cannot be used to manipulate the RStudio Server Pro Home Page. To disable the home page:

/etc/rstudio/rserver.conf

server-user-home-page=0

12.2.5 Disable Multiple Session Support

Even with the Home Page disabled, a user can still open new sessions via Session / New Session which will open a new IDE instance outside of the host page. To prevent this:

/etc/rstudio/rserver.conf

server-multiple-sessions=0

If multiple sessions are disabled, the Home Page is automatically turned off, so not necessary to include both settings.

12.2.6 Serve the Example Page

Serve the folder /usr/lib/rstudio-server/extras/tutorial with a web server. For example, change to that directory in a terminal and run this command:

python -m SimpleHTTPServer 8080

Load http://localhost:8080/demo.htm in a web browser and you should see the page shown earlier.

12.3 Interface

You can access the Tutorial API by including rstudio.js within your host page. This will enable you to instantiate an RStudio object that has a connection to the RStudio IDE within an IFrame. For example, if the IDE were hosted in an IFrame as follows:

<iframe id="rstudio" src="http://localhost:8787"></iframe>

Then you would instantiate an RStudio object as follows:

var RStudio = new RStudio(document.getElementById("rstudio"), 
                          "http://localhost:8787",
                          function() { // onReady callback
                             console.log("API is ready!");
                          },
                          function(responseJSON) { // parent-notify callback
                             console.log(responseJSON);
                          });

The third argument is a callback that will be invoked once the RStudio API is ready to be called (i.e. once the IDE has loaded). Note that you should be sure to instantiate this object before the IFrame containing the IDE is fully loaded (if you don’t then you might miss the onReady callback). The best way to do this is to either:

  1. Create the object immediately after defining the IFrame within the host page; or

  2. More conservatively, create the IFrame, then create the object, then provide the src to the IFrame (this is however almost certainly not necessary and #1 should suffice).

The fourth argument is a callback that will be invoked when certain events described below in Tutorial API Callbacks are emitted by the IDE. These are only emitted if tutorial-api-parent-notify-enabled=1 was set as described earlier. The response will be a text string in JSON format, as described below in Tutorial API Callbacks.

12.4 Tutorial API Methods

Methods are asynchronous and do not directly return a result.

If Report Result is true below then that API will attempt to invoke a success or error callback when it completes, but this is never guaranteed.

Methods which report a result take an optional final string parameter callerID which will be returned in both success and error callbacks. This can be used to correlate calls and responses.

The RStudio object supports the following methods:

Method Description Reports Result
isReady() Is the RStudio API available yet? (has the IDE loaded) No
consoleInput(code) Type input in the R console and execute it. No
consoleClear() Clear all previous input and output from the console. No
consoleMaximize() Maximize the console so it occupies the full height of the IDE. No
executeR(code) Execute arbitrary R code within the global environment. No
openFile(file, location) Open the specified source file and (optionally) navigate it to a specific location. The location parameter can either be a line number (e.g. 42) or a regular expression delimited by / (e.g. /foo/). No
helpTopic(topic) Navigate the help pane to a topic. The topic should be a namespace qualified reference to package documentation (e.g. graphics::plot). Note that help topics defined within the base package do not need qualification. No
helpDoc(doc) Show a markdown (.md) or R Markdown (.Rmd) document within the help pane. No
saveAllSourceDocs() Save all unsaved source documents. No
quitSession() Quit session. User cannot cancel but is prompted to save files and workspace if needed. No
createProjFromGit(repoUrl, projDir, parentDir, [callerID]) Clone a project from Git and open it. Yes
createNewProj(projDir, parentDir, createRepo, [callerID]) Create and open a new project. Yes
openProj(projFile, [callerID]) Open an existing project, can specify existing .Rproj, or just the folder. Yes
getState([callerID]) Request info on current RStudio IDE state. Yes

12.4.1 Example Calls

Here are some sample JavaScript calls, followed by the response JSON.

12.4.1.1 Clone project from github and open it (with callerID = ‘abcd’)

createProjFromGit('https://github.com/rstudio/rstudioapi', 'rstudioapi', '~/R', 'abcd');
{
  "message":"success",
  "api":"createProjFromGit",
  "result":"",
  "callerID":"abcd"
}

12.4.1.2 Create an new project but don’t create a git repo (no callerID)

createNewProj('myproj', '~/R', false);
{
  "message":"success",
  "api":"createNewProj",
  "result":""
}

12.4.1.3 Try to open a project that doesn’t exist

openProj('~/myproj', 'abcd');
{
  "message":"error",
  "api":"openProj",
  "result":"Unable to find .Rproj file in [~/myproj]",
  "callerID":"abcd"
}

12.5 Tutorial API Callbacks

As seen in the examples above, the callback returns JSON. The following are examples of calls that trigger callbacks.

Method Description Example payload
getState response from getState See examples below
error a prior API call failed {“message”: “error”, “api”: “createProjFromGit”, “result”: “access denied”, “callerID”: “abcd”}
success a prior API call succeeded {“message”: “success”, “api”: “createProjFromGit”, “callerID”: “abcd”}

There are also callbacks sent directly by RStudio (i.e. not in response to Tutorial API calls).

Method Description Example payload
fileSave contents of a file loaded in RStudio IDE were saved (including auto-save of content and/or metadata) {“message”: “fileSave”}
sessionDisconnect connection between RStudio IDE and its rsession process was closed {“message”: “sessionDisconnect”}
sessionSuspend the rsession process has been suspended {“message”: “sessionSuspend”}

12.5.1 getState

The getState() method returns the path to the currently loaded .Rproj (if any) and any git remotes.

The results come via the callback. Here are some examples.

12.5.1.1 Project with remotes

{
  "message": "getState",
  "callerID": "abcd",
  "project": "~/aaa/aaa.Rproj",
  "remotes": [
    {
      "active": true,
      "remote": "origin",
      "type": "fetch",
      "url": "https://github.com/rstudio/aaa"
    },
    {
      "active": true,
      "remote": "origin",
      "type": "push",
      "url": "https://github.com/rstudio/aaa"
    }
  ]
}

12.5.1.2 Project with no remotes

{
  "message": "getState",
  "callerID": "abcd",
  "project": "~/localproj/localproj.Rproj",
  "remotes": []
}

12.5.1.3 No project and no remotes

{
  "message": "getState",
  "callerID": "abcd",
  "project": null,
  "remotes": []
}