10 Connect Server API Cookbook
This section contains recipes for writing scripts that use the Connect Server API. It is assumed that you know the R Programming Language, but the recipes are intended to be straightforward enough to be implemented in any programming language you wish to use.
10.1 Configuring Your Scripts
It may be useful to store your RStudio Connect server URL and your API key in an environment variable, so that you can share any tools you create without exposing your personal information to other users. For example:
# ~/.Renviron
# Note that the connectServer string must have a trailing slash
RSTUDIO_CONNECT_API_KEY="mysupersecretapikey"
RSTUDIO_CONNECT_SERVER="https://connect.example.com/"
The .Renviron
file will be loaded in every R session spawned under your
user account.
10.2 Recipes
10.2.1 Detect Whether RStudio Connect Has Your Local R Version
- Obtain the server path and API keys from environment variables
- Obtain your local R version using
R.version
- Call the “Get R Installation Info” endpoint. See the API Documentation for more information.
- Parse the response using
httr::content
. - Check the response for the local R version. If it is not listed, the RStudio Connect server does not contain the local R version.
# set up environment
# Note that the connectServer string must have a trailing slash
connectServer <- Sys.getenv("RSTUDIO_CONNECT_SERVER")
apiKey <- Sys.getenv("RSTUDIO_CONNECT_API_KEY")
library(httr)
myRVersion <- paste(R.version$major, R.version$minor, sep = ".")
resp <- GET(
paste0(connectServer, "__api__/v1/server_settings/r"),
add_headers(Authorization = paste("Key", apiKey))
)
resp <- content(resp, as="parsed")
if (!(myRVersion %in% unlist(resp))) {
print(paste("Cannot find R version", myRVersion,"on the RStudio Connect server"))
} else {
print("The local R version was found on the RStudio Connect server")
}
10.2.2 Use Keyset (Cursor) Pagination
The following snippet pages through the audit logs, which uses keyset pagination, starting from the most recent entries, 25 entries at a time.
- Obtain the server path and API keys from environment variables.
- Call the “Get audit logs” endpoint to get the first page. See the API Documentation for more information.
- Parse the response using
httr::content
. - Print the current page.
- Repeat steps 1 through 3 until there are no more results. Note also
that the
paging.next
property in the response is the URL of the next page.
# set up environment
library(httr)
# Note that the connectServer string must have a trailing slash
connectServer <- Sys.getenv("RSTUDIO_CONNECT_SERVER")
apiKey <- Sys.getenv("RSTUDIO_CONNECT_API_KEY")
# get audit logs
authHeader <- add_headers(Authorization = paste("Key", apiKey))
resp <- GET(
paste0(connectServer, "__api__/v1/audit_logs?ascOrder=false&limit=25"),
authHeader
)
payload <- content(resp)
# print first 25!
print(payload$result)
# now step through the remaining audit logs
while(!is.null(payload$paging[["next"]])) {
resp <- GET(payload$paging[["next"]], authHeader)
payload <- content(resp)
# print the next 25
print(payload$result)
}
10.2.3 Use Offset Pagination
The following snippet pages through the user’s list, which uses offset pagination, 25 entries at a time.
- Obtain the server path and API keys from environment variables.
- Call the “Get all users” endpoint to get the first page. See the API Documentation for more information.
- Parse the response using
httr::content
. - Print the current page.
- Repeat steps 1 through 3 until there is no more “next” page. Note
also that the query parameter
page_number
determines the page to return.
# set up environment
library(httr)
# Note that the connectServer string must have a trailing slash
connectServer <- Sys.getenv("RSTUDIO_CONNECT_SERVER")
apiKey <- Sys.getenv("RSTUDIO_CONNECT_API_KEY")
# get user's list
authHeader <- add_headers(Authorization = paste("Key", apiKey))
apiPrefix <- "__api__/v1/users?page_size=25"
resp <- GET(
paste0(connectServer, apiPrefix),
authHeader
)
# get the first page
payload <- content(resp)
# and step through the pages, printing out the results (if any)
while(length(payload$result) > 0) {
# print the result
print(payload$result)
# get the next page
nextPage <- payload$current_page + 1
resp <- GET(
paste0(connectServer, apiPrefix, "&page_number=", nextPage),
authHeader
)
payload <- content(resp)
}
10.2.4 Create an RStudio Connect User from LDAP or OAuth2
The following snippets search for a user in LDAP or OAuth2 and then create an RStudio Connect account for that user.
There are two steps:
- Search for the user via the
/users/remote
endpoint. A user with no account on Connect will lack aguid
. Note thetemp_ticket
for the desired user account. - Use the
PUT /users
endpoint with thetemp_ticket
to create a corresponding account on RStudio Connect.
10.2.4.1 Search for a User
# set up environment
library(httr)
# Note that the connectServer string must have a trailing slash
connectServer <- Sys.getenv("RSTUDIO_CONNECT_SERVER")
apiKey <- Sys.getenv("RSTUDIO_CONNECT_API_KEY")
# set the search parameter
prefix <- "julie"
# make the query request
authHeader <- paste("Key", apiKey)
response <- GET(
paste0(connectServer, "__api__/v1/users/remote"),
add_headers(Authorization = authHeader),
query = list(prefix = prefix)
)
results <- content(response)$results
# print the results of the API call
formatGuid <- function(guid) {
if (is.null(guid))
"NULL"
else
guid
}
cat(sprintf("FIRST\tLAST\tUSERNAME\tGUID\n"))
for (user in results) {
cat(
sprintf(
"%s\t%s\t%s\t\t%s\n",
user$first_name,
user$last_name,
user$username,
formatGuid(user$guid)
)
)
}
The output looks like the following:
FIRST LAST USERNAME GUID
Julie Goolly julie1 15f5f51d-08ff-4e5b-beba-4ccf24e248dd
Julie Jolly julie2 NULL
In this particular case, there are two users matching the search for the prefix
julie
. The user julie1
has a GUID
value, which means that this user
already has an account in RStudio Connect. The user julie2
does not yet have
an account in RStudio Connect.
Included in the API response for each user is a temp_ticket
value that can
be used to give the user an account in RStudio Connect. In the example above,
the second user, julie2
, needs an account, so you will need that user’s
temp_ticket
:
tempTicket <- results[[2]]$temp_ticket
You can use this tempTicket
value in the next section to create the account.
10.2.4.2 Create an RStudio Connect User Account
Using the tempTicket
value from the previous section, you can give the user
an RStudio Connect account with an HTTP PUT request:
# use a tempTicket value from searching /users/remote
response <- PUT(
paste0(connectServer, "__api__/v1/users"),
add_headers(Authorization = authHeader),
body = list(temp_ticket = tempTicket),
encode = "json"
)
print(content(response))
When the call succeeds, the response will contain a non-NULL guid
value,
which is a unique identifier for the user account.
If the user already exists in Connect, the response will contain an error:
$error
[1] "The requested username is already in use."
10.2.5 Get User Usage of Shiny Applications
The following snippet pages through shiny application usage. It returns information in pages and follows the keyset pagination model. If you haven’t yet, you may want to review that recipe above.
- Obtain the server path and API keys from environment variables.
- Call the “Get shiny app usage” endpoint to get the first page. See the API Documentation for more information.
- Parse the response using
httr::content
. - Print the current page.
- Repeat steps 1 through 3 until there are no more results. Note also
that the
paging.next
property in the response is the URL of the next page.
# set up environment
library(httr)
# Note that the connectServer string must have a trailing slash
connectServer <- Sys.getenv("RSTUDIO_CONNECT_SERVER")
apiKey <- Sys.getenv("RSTUDIO_CONNECT_API_KEY")
# get usage information
authHeader <- add_headers(Authorization = paste("Key", apiKey))
usageURL <- paste0(connectServer, "__api__/v1/instrumentation/shiny/usage?limit=25")
resp <- GET(usageURL, authHeader)
payload <- content(resp)
# print first 25!
print(payload$result)
# now step through the remaining audit logs
while(!is.null(payload$paging[["next"]])) {
resp <- GET(payload$paging[["next"]], authHeader)
payload <- content(resp)
# print the next 25
print(payload$result)
}