Databricks Integrations with R
Problem
You are building an interactive R application which needs to act as the person visiting the application when accessing a private Databricks resource. The content must authenticate to Databricks using the viewer’s Databricks credentials. For example, reading data from a Databricks Unity Catalog table that has row-level permissions and each content viewer has a different level of data access.
Solution
The examples below illustrate how to use the OAuth integrations feature of Posit Connect to delegate authorization to the data provider. These examples use the viewer’s OAuth access token to call the Databricks API on behalf of the content viewer, allowing content to access private Databricks resources as the content viewer.
When publishing the content to Connect make sure the following environment variables are set for the deployed content:
DATABRICKS_HOST
DATABRICKS_PATH
renv.lock
{
"R": {
"Version": "4.3.0",
"Repositories": [
{
"Name": "CRAN",
"URL": "https://cloud.r-project.org"
}
]
},
"Packages": {
"DBI": {
"Package": "DBI",
"Version": "1.2.3",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"methods"
],
"Hash": "065ae649b05f1ff66bb0c793107508f5"
},
"R6": {
"Package": "R6",
"Version": "2.5.1",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R"
],
"Hash": "470851b6d5d0ac559e9d01bb352b4021"
},
"Rcpp": {
"Package": "Rcpp",
"Version": "1.0.13",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"methods",
"utils"
],
"Hash": "f27411eb6d9c3dada5edd444b8416675"
},
"askpass": {
"Package": "askpass",
"Version": "1.2.0",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"sys"
],
"Hash": "cad6cf7f1d5f6e906700b9d3e718c796"
},
"bit": {
"Package": "bit",
"Version": "4.0.5",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R"
],
"Hash": "d242abec29412ce988848d0294b208fd"
},
"bit64": {
"Package": "bit64",
"Version": "4.0.5",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"bit",
"methods",
"stats",
"utils"
],
"Hash": "9fe98599ca456d6552421db0d6772d8f"
},
"blob": {
"Package": "blob",
"Version": "1.2.4",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"methods",
"rlang",
"vctrs"
],
"Hash": "40415719b5a479b87949f3aa0aee737c"
},
"cli": {
"Package": "cli",
"Version": "3.6.3",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"utils"
],
"Hash": "b21916dd77a27642b447374a5d30ecf3"
},
"connectapi": {
"Package": "connectapi",
"Version": "0.3.0",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R6",
"bit64",
"fs",
"glue",
"httr",
"jsonlite",
"lifecycle",
"magrittr",
"purrr",
"rlang",
"tibble",
"uuid",
"vctrs"
],
"Hash": "f5206247a25db881071783261b837afb"
},
"cpp11": {
"Package": "cpp11",
"Version": "0.5.0",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R"
],
"Hash": "91570bba75d0c9d3f1040c835cee8fba"
},
"crayon": {
"Package": "crayon",
"Version": "1.5.3",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"grDevices",
"methods",
"utils"
],
"Hash": "859d96e65ef198fd43e82b9628d593ef"
},
"curl": {
"Package": "curl",
"Version": "5.2.2",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R"
],
"Hash": "8f27335f2bcff4d6035edcc82d7d46de"
},
"dbplyr": {
"Package": "dbplyr",
"Version": "2.5.0",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"DBI",
"R",
"R6",
"blob",
"cli",
"dplyr",
"glue",
"lifecycle",
"magrittr",
"methods",
"pillar",
"purrr",
"rlang",
"tibble",
"tidyr",
"tidyselect",
"utils",
"vctrs",
"withr"
],
"Hash": "39b2e002522bfd258039ee4e889e0fd1"
},
"dplyr": {
"Package": "dplyr",
"Version": "1.1.4",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"R6",
"cli",
"generics",
"glue",
"lifecycle",
"magrittr",
"methods",
"pillar",
"rlang",
"tibble",
"tidyselect",
"utils",
"vctrs"
],
"Hash": "fedd9d00c2944ff00a0e2696ccf048ec"
},
"ellipsis": {
"Package": "ellipsis",
"Version": "0.3.2",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"rlang"
],
"Hash": "bb0eec2fe32e88d9e2836c2f73ea2077"
},
"fansi": {
"Package": "fansi",
"Version": "1.0.6",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"grDevices",
"utils"
],
"Hash": "962174cf2aeb5b9eea581522286a911f"
},
"fastmap": {
"Package": "fastmap",
"Version": "1.2.0",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "aa5e1cd11c2d15497494c5292d7ffcc8"
},
"fs": {
"Package": "fs",
"Version": "1.6.4",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"methods"
],
"Hash": "15aeb8c27f5ea5161f9f6a641fafd93a"
},
"generics": {
"Package": "generics",
"Version": "0.1.3",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"methods"
],
"Hash": "15e9634c0fcd294799e9b2e929ed1b86"
},
"glue": {
"Package": "glue",
"Version": "1.7.0",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"methods"
],
"Hash": "e0b3a53876554bd45879e596cdb10a52"
},
"hms": {
"Package": "hms",
"Version": "1.1.3",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"lifecycle",
"methods",
"pkgconfig",
"rlang",
"vctrs"
],
"Hash": "b59377caa7ed00fa41808342002138f9"
},
"httpuv": {
"Package": "httpuv",
"Version": "1.6.15",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"R6",
"Rcpp",
"later",
"promises",
"utils"
],
"Hash": "d55aa087c47a63ead0f6fc10f8fa1ee0"
},
"httr": {
"Package": "httr",
"Version": "1.4.7",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"R6",
"curl",
"jsonlite",
"mime",
"openssl"
],
"Hash": "ac107251d9d9fd72f0ca8049988f1d7f"
},
"httr2": {
"Package": "httr2",
"Version": "1.0.3",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"R6",
"cli",
"curl",
"glue",
"lifecycle",
"magrittr",
"openssl",
"rappdirs",
"rlang",
"vctrs",
"withr"
],
"Hash": "10d93e97faad6b629301bb3a2fd23378"
},
"jsonlite": {
"Package": "jsonlite",
"Version": "1.8.8",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"methods"
],
"Hash": "e1b9c55281c5adc4dd113652d9e26768"
},
"later": {
"Package": "later",
"Version": "1.3.2",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"Rcpp",
"rlang"
],
"Hash": "a3e051d405326b8b0012377434c62b37"
},
"lifecycle": {
"Package": "lifecycle",
"Version": "1.0.4",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"cli",
"glue",
"rlang"
],
"Hash": "b8552d117e1b808b09a832f589b79035"
},
"magrittr": {
"Package": "magrittr",
"Version": "2.0.3",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R"
],
"Hash": "7ce2733a9826b3aeb1775d56fd305472"
},
"mime": {
"Package": "mime",
"Version": "0.12",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"tools"
],
"Hash": "18e9c28c1d3ca1560ce30658b22ce104"
},
"odbc": {
"Package": "odbc",
"Version": "1.5.0",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"DBI",
"R",
"Rcpp",
"bit64",
"blob",
"cli",
"hms",
"lifecycle",
"methods",
"rlang"
],
"Hash": "0609d24c52744c675f8578622c33d5fa"
},
"openssl": {
"Package": "openssl",
"Version": "2.2.1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"askpass"
],
"Hash": "c62edf62de70cadf40553e10c739049d"
},
"pillar": {
"Package": "pillar",
"Version": "1.9.0",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"cli",
"fansi",
"glue",
"lifecycle",
"rlang",
"utf8",
"utils",
"vctrs"
],
"Hash": "15da5a8412f317beeee6175fbc76f4bb"
},
"pkgconfig": {
"Package": "pkgconfig",
"Version": "2.0.3",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"utils"
],
"Hash": "01f28d4278f15c76cddbea05899c5d6f"
},
"plumber": {
"Package": "plumber",
"Version": "1.2.2",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"R6",
"crayon",
"ellipsis",
"httpuv",
"jsonlite",
"lifecycle",
"magrittr",
"mime",
"promises",
"rlang",
"sodium",
"stringi",
"swagger",
"webutils"
],
"Hash": "0c671ac357592beb716f19b818b72e50"
},
"promises": {
"Package": "promises",
"Version": "1.3.0",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R6",
"Rcpp",
"fastmap",
"later",
"magrittr",
"rlang",
"stats"
],
"Hash": "434cd5388a3979e74be5c219bcd6e77d"
},
"purrr": {
"Package": "purrr",
"Version": "1.0.2",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"cli",
"lifecycle",
"magrittr",
"rlang",
"vctrs"
],
"Hash": "1cba04a4e9414bdefc9dcaa99649a8dc"
},
"rappdirs": {
"Package": "rappdirs",
"Version": "0.3.3",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R"
],
"Hash": "5e3c5dc0b071b21fa128676560dbe94d"
},
"renv": {
"Package": "renv",
"Version": "1.0.7",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"utils"
],
"Hash": "397b7b2a265bc5a7a06852524dabae20"
},
"rlang": {
"Package": "rlang",
"Version": "1.1.4",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"utils"
],
"Hash": "3eec01f8b1dee337674b2e34ab1f9bc1"
},
"sodium": {
"Package": "sodium",
"Version": "1.3.1",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Hash": "dd86d6fd2a01d4eb3777dfdee7076d56"
},
"stringi": {
"Package": "stringi",
"Version": "1.8.4",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"stats",
"tools",
"utils"
],
"Hash": "39e1144fd75428983dc3f63aa53dfa91"
},
"stringr": {
"Package": "stringr",
"Version": "1.5.1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"cli",
"glue",
"lifecycle",
"magrittr",
"rlang",
"stringi",
"vctrs"
],
"Hash": "960e2ae9e09656611e0b8214ad543207"
},
"swagger": {
"Package": "swagger",
"Version": "5.17.14.1",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "cd09053b2f1e87c0fa6c1c470e54ebb8"
},
"sys": {
"Package": "sys",
"Version": "3.4.2",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Hash": "3a1be13d68d47a8cd0bfd74739ca1555"
},
"tibble": {
"Package": "tibble",
"Version": "3.2.1",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"fansi",
"lifecycle",
"magrittr",
"methods",
"pillar",
"pkgconfig",
"rlang",
"utils",
"vctrs"
],
"Hash": "a84e2cc86d07289b3b6f5069df7a004c"
},
"tidyr": {
"Package": "tidyr",
"Version": "1.3.1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"cli",
"cpp11",
"dplyr",
"glue",
"lifecycle",
"magrittr",
"purrr",
"rlang",
"stringr",
"tibble",
"tidyselect",
"utils",
"vctrs"
],
"Hash": "915fb7ce036c22a6a33b5a8adb712eb1"
},
"tidyselect": {
"Package": "tidyselect",
"Version": "1.2.1",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"cli",
"glue",
"lifecycle",
"rlang",
"vctrs",
"withr"
],
"Hash": "829f27b9c4919c16b593794a6344d6c0"
},
"utf8": {
"Package": "utf8",
"Version": "1.2.4",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R"
],
"Hash": "62b65c52671e6665f803ff02954446e9"
},
"uuid": {
"Package": "uuid",
"Version": "1.2-1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R"
],
"Hash": "34e965e62a41fcafb1ca60e9b142085b"
},
"vctrs": {
"Package": "vctrs",
"Version": "0.6.5",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"cli",
"glue",
"lifecycle",
"rlang"
],
"Hash": "c03fa420630029418f7e6da3667aac4a"
},
"webutils": {
"Package": "webutils",
"Version": "1.2.1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"curl",
"jsonlite"
],
"Hash": "498fc2f392a45fe30526f69b73cdeeb7"
},
"withr": {
"Package": "withr",
"Version": "3.0.1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"grDevices",
"graphics"
],
"Hash": "07909200e8bbe90426fbfeb73e1e27aa"
}
}
}
app.R
library(connectapi)
library(dbplyr)
library(dplyr)
library(httr2)
library(odbc)
library(plumber)
#* Return the Databricks username
#* @get /whoami
function(){
databricks_user(session)$displayName
}
#* Return data from Databricks
#* @get /data
function(){
<- dbConnect(
con ::databricks(),
odbchttpPath = Sys.getenv("DATABRICKS_PATH"),
authMech = 11,
auth_flow = 0,
auth_accesstoken = databricks_token(session)
)<- tbl(
data
con,in_catalog("samples", "nyctaxi", "trips")
|>
) head(10) |>
collect()
data
}
# call the databricks "current user" API to get
# information about the authenticated user.
<- function(session) {
databricks_user <- Sys.getenv("DATABRICKS_HOST")
host <- databricks_token(session)
token
<- file.path(
url paste0("https://", host),
"api/2.0/preview/scim/v2/Me",
fsep = "/"
)<- httr2::request(url) |>
resp ::req_auth_bearer_token(token) |>
httr2::req_retry(max_tries = 1) |>
httr2::req_perform()
httr2
<- httr2::resp_body_json(resp)
resp_body
resp_body
}
# obtain a databricks OAuth token.
# 1. if running on Posit Connect, exhanges Connect's user-session-token for the viewer's Databricks OAuth access token
# 2. if running on Posit Workbench, read the Databricks token from the workbench managed DATABRICKS_CONFIG_FILE
# 3. if running locally, read the Databricks token from the DATABRICKS_TOKEN environment var
<- function(session) {
databricks_token <- Sys.getenv("DATABRICKS_HOST")
host <- NULL
token
# if running on Connect
if (Sys.getenv("RSTUDIO_PRODUCT") == "CONNECT") {
# init Posit Connect API client
<- connect()
client # read the user-session-token header
<- session$request$HTTP_POSIT_CONNECT_USER_SESSION_TOKEN
user_session_token # exchange session token for viewer OAuth access token
<- get_oauth_credentials(client, user_session_token)
credentials <- credentials$access_token
token
# not running on Connect, so check for a .databrickscfg file (automatically set by workbench)
else if (Sys.getenv("DATABRICKS_CONFIG_FILE") != "") {
} <- get(".rs.api.getDatabricksToken")
getDatabricksToken <- getDatabricksToken(host)
token
# finally, look for a databricks token (must be set by the user when running locally)
else {
} <- Sys.getenv("DATABRICKS_TOKEN")
token
}
token }
Running the app locally
Terminal
export DATABRICKS_HOST="<databricks-sql-warehouse-server-hostname>"
export DATABRICKS_PATH="<databricks-sql-warehouse-http-path>"
# TOKEN is only required when running the example locally
DATABRICKS_TOKEN="<databricks-token>" R -e 'plumber::pr_run(pr=plumber::pr("app.R"))'
renv.lock
{
"R": {
"Version": "4.3.0",
"Repositories": [
{
"Name": "CRAN",
"URL": "https://cloud.r-project.org"
}
]
},
"Packages": {
"DBI": {
"Package": "DBI",
"Version": "1.2.3",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"methods"
],
"Hash": "065ae649b05f1ff66bb0c793107508f5"
},
"R6": {
"Package": "R6",
"Version": "2.5.1",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R"
],
"Hash": "470851b6d5d0ac559e9d01bb352b4021"
},
"Rcpp": {
"Package": "Rcpp",
"Version": "1.0.13",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"methods",
"utils"
],
"Hash": "f27411eb6d9c3dada5edd444b8416675"
},
"askpass": {
"Package": "askpass",
"Version": "1.2.0",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"sys"
],
"Hash": "cad6cf7f1d5f6e906700b9d3e718c796"
},
"bit": {
"Package": "bit",
"Version": "4.0.5",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R"
],
"Hash": "d242abec29412ce988848d0294b208fd"
},
"bit64": {
"Package": "bit64",
"Version": "4.0.5",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"bit",
"methods",
"stats",
"utils"
],
"Hash": "9fe98599ca456d6552421db0d6772d8f"
},
"blob": {
"Package": "blob",
"Version": "1.2.4",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"methods",
"rlang",
"vctrs"
],
"Hash": "40415719b5a479b87949f3aa0aee737c"
},
"cli": {
"Package": "cli",
"Version": "3.6.3",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"utils"
],
"Hash": "b21916dd77a27642b447374a5d30ecf3"
},
"connectapi": {
"Package": "connectapi",
"Version": "0.3.0",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R6",
"bit64",
"fs",
"glue",
"httr",
"jsonlite",
"lifecycle",
"magrittr",
"purrr",
"rlang",
"tibble",
"uuid",
"vctrs"
],
"Hash": "f5206247a25db881071783261b837afb"
},
"cpp11": {
"Package": "cpp11",
"Version": "0.5.0",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R"
],
"Hash": "91570bba75d0c9d3f1040c835cee8fba"
},
"crayon": {
"Package": "crayon",
"Version": "1.5.3",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"grDevices",
"methods",
"utils"
],
"Hash": "859d96e65ef198fd43e82b9628d593ef"
},
"curl": {
"Package": "curl",
"Version": "5.2.2",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R"
],
"Hash": "8f27335f2bcff4d6035edcc82d7d46de"
},
"dbplyr": {
"Package": "dbplyr",
"Version": "2.5.0",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"DBI",
"R",
"R6",
"blob",
"cli",
"dplyr",
"glue",
"lifecycle",
"magrittr",
"methods",
"pillar",
"purrr",
"rlang",
"tibble",
"tidyr",
"tidyselect",
"utils",
"vctrs",
"withr"
],
"Hash": "39b2e002522bfd258039ee4e889e0fd1"
},
"dplyr": {
"Package": "dplyr",
"Version": "1.1.4",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"R6",
"cli",
"generics",
"glue",
"lifecycle",
"magrittr",
"methods",
"pillar",
"rlang",
"tibble",
"tidyselect",
"utils",
"vctrs"
],
"Hash": "fedd9d00c2944ff00a0e2696ccf048ec"
},
"ellipsis": {
"Package": "ellipsis",
"Version": "0.3.2",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"rlang"
],
"Hash": "bb0eec2fe32e88d9e2836c2f73ea2077"
},
"fansi": {
"Package": "fansi",
"Version": "1.0.6",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"grDevices",
"utils"
],
"Hash": "962174cf2aeb5b9eea581522286a911f"
},
"fastmap": {
"Package": "fastmap",
"Version": "1.2.0",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "aa5e1cd11c2d15497494c5292d7ffcc8"
},
"fs": {
"Package": "fs",
"Version": "1.6.4",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"methods"
],
"Hash": "15aeb8c27f5ea5161f9f6a641fafd93a"
},
"generics": {
"Package": "generics",
"Version": "0.1.3",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"methods"
],
"Hash": "15e9634c0fcd294799e9b2e929ed1b86"
},
"glue": {
"Package": "glue",
"Version": "1.7.0",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"methods"
],
"Hash": "e0b3a53876554bd45879e596cdb10a52"
},
"hms": {
"Package": "hms",
"Version": "1.1.3",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"lifecycle",
"methods",
"pkgconfig",
"rlang",
"vctrs"
],
"Hash": "b59377caa7ed00fa41808342002138f9"
},
"httpuv": {
"Package": "httpuv",
"Version": "1.6.15",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"R6",
"Rcpp",
"later",
"promises",
"utils"
],
"Hash": "d55aa087c47a63ead0f6fc10f8fa1ee0"
},
"httr": {
"Package": "httr",
"Version": "1.4.7",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"R6",
"curl",
"jsonlite",
"mime",
"openssl"
],
"Hash": "ac107251d9d9fd72f0ca8049988f1d7f"
},
"httr2": {
"Package": "httr2",
"Version": "1.0.3",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"R6",
"cli",
"curl",
"glue",
"lifecycle",
"magrittr",
"openssl",
"rappdirs",
"rlang",
"vctrs",
"withr"
],
"Hash": "10d93e97faad6b629301bb3a2fd23378"
},
"jsonlite": {
"Package": "jsonlite",
"Version": "1.8.8",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"methods"
],
"Hash": "e1b9c55281c5adc4dd113652d9e26768"
},
"later": {
"Package": "later",
"Version": "1.3.2",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"Rcpp",
"rlang"
],
"Hash": "a3e051d405326b8b0012377434c62b37"
},
"lifecycle": {
"Package": "lifecycle",
"Version": "1.0.4",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"cli",
"glue",
"rlang"
],
"Hash": "b8552d117e1b808b09a832f589b79035"
},
"magrittr": {
"Package": "magrittr",
"Version": "2.0.3",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R"
],
"Hash": "7ce2733a9826b3aeb1775d56fd305472"
},
"mime": {
"Package": "mime",
"Version": "0.12",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"tools"
],
"Hash": "18e9c28c1d3ca1560ce30658b22ce104"
},
"odbc": {
"Package": "odbc",
"Version": "1.5.0",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"DBI",
"R",
"Rcpp",
"bit64",
"blob",
"cli",
"hms",
"lifecycle",
"methods",
"rlang"
],
"Hash": "0609d24c52744c675f8578622c33d5fa"
},
"openssl": {
"Package": "openssl",
"Version": "2.2.1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"askpass"
],
"Hash": "c62edf62de70cadf40553e10c739049d"
},
"pillar": {
"Package": "pillar",
"Version": "1.9.0",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"cli",
"fansi",
"glue",
"lifecycle",
"rlang",
"utf8",
"utils",
"vctrs"
],
"Hash": "15da5a8412f317beeee6175fbc76f4bb"
},
"pkgconfig": {
"Package": "pkgconfig",
"Version": "2.0.3",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"utils"
],
"Hash": "01f28d4278f15c76cddbea05899c5d6f"
},
"plumber": {
"Package": "plumber",
"Version": "1.2.2",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"R6",
"crayon",
"ellipsis",
"httpuv",
"jsonlite",
"lifecycle",
"magrittr",
"mime",
"promises",
"rlang",
"sodium",
"stringi",
"swagger",
"webutils"
],
"Hash": "0c671ac357592beb716f19b818b72e50"
},
"promises": {
"Package": "promises",
"Version": "1.3.0",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R6",
"Rcpp",
"fastmap",
"later",
"magrittr",
"rlang",
"stats"
],
"Hash": "434cd5388a3979e74be5c219bcd6e77d"
},
"purrr": {
"Package": "purrr",
"Version": "1.0.2",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"cli",
"lifecycle",
"magrittr",
"rlang",
"vctrs"
],
"Hash": "1cba04a4e9414bdefc9dcaa99649a8dc"
},
"rappdirs": {
"Package": "rappdirs",
"Version": "0.3.3",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R"
],
"Hash": "5e3c5dc0b071b21fa128676560dbe94d"
},
"renv": {
"Package": "renv",
"Version": "1.0.7",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"utils"
],
"Hash": "397b7b2a265bc5a7a06852524dabae20"
},
"rlang": {
"Package": "rlang",
"Version": "1.1.4",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"utils"
],
"Hash": "3eec01f8b1dee337674b2e34ab1f9bc1"
},
"sodium": {
"Package": "sodium",
"Version": "1.3.1",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Hash": "dd86d6fd2a01d4eb3777dfdee7076d56"
},
"stringi": {
"Package": "stringi",
"Version": "1.8.4",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"stats",
"tools",
"utils"
],
"Hash": "39e1144fd75428983dc3f63aa53dfa91"
},
"stringr": {
"Package": "stringr",
"Version": "1.5.1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"cli",
"glue",
"lifecycle",
"magrittr",
"rlang",
"stringi",
"vctrs"
],
"Hash": "960e2ae9e09656611e0b8214ad543207"
},
"swagger": {
"Package": "swagger",
"Version": "5.17.14.1",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "cd09053b2f1e87c0fa6c1c470e54ebb8"
},
"sys": {
"Package": "sys",
"Version": "3.4.2",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Hash": "3a1be13d68d47a8cd0bfd74739ca1555"
},
"tibble": {
"Package": "tibble",
"Version": "3.2.1",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"fansi",
"lifecycle",
"magrittr",
"methods",
"pillar",
"pkgconfig",
"rlang",
"utils",
"vctrs"
],
"Hash": "a84e2cc86d07289b3b6f5069df7a004c"
},
"tidyr": {
"Package": "tidyr",
"Version": "1.3.1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"cli",
"cpp11",
"dplyr",
"glue",
"lifecycle",
"magrittr",
"purrr",
"rlang",
"stringr",
"tibble",
"tidyselect",
"utils",
"vctrs"
],
"Hash": "915fb7ce036c22a6a33b5a8adb712eb1"
},
"tidyselect": {
"Package": "tidyselect",
"Version": "1.2.1",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"cli",
"glue",
"lifecycle",
"rlang",
"vctrs",
"withr"
],
"Hash": "829f27b9c4919c16b593794a6344d6c0"
},
"utf8": {
"Package": "utf8",
"Version": "1.2.4",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R"
],
"Hash": "62b65c52671e6665f803ff02954446e9"
},
"uuid": {
"Package": "uuid",
"Version": "1.2-1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R"
],
"Hash": "34e965e62a41fcafb1ca60e9b142085b"
},
"vctrs": {
"Package": "vctrs",
"Version": "0.6.5",
"Source": "Repository",
"Repository": "https://packagemanager.posit.co/cran/__linux__/jammy/latest",
"Requirements": [
"R",
"cli",
"glue",
"lifecycle",
"rlang"
],
"Hash": "c03fa420630029418f7e6da3667aac4a"
},
"webutils": {
"Package": "webutils",
"Version": "1.2.1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"curl",
"jsonlite"
],
"Hash": "498fc2f392a45fe30526f69b73cdeeb7"
},
"withr": {
"Package": "withr",
"Version": "3.0.1",
"Source": "Repository",
"Repository": "CRAN",
"Requirements": [
"R",
"grDevices",
"graphics"
],
"Hash": "07909200e8bbe90426fbfeb73e1e27aa"
}
}
}
app.R
library(connectapi)
library(dbplyr)
library(dplyr)
library(gt)
library(httr2)
library(odbc)
library(shiny)
<- fluidPage(
ui mainPanel(
textOutput("display_name"),
gt_output("data")
))
<- function(input, output, session) {
server
<- reactive({
user databricks_user(session)
})
$display_name <- renderText({
outputpaste0("Hello, ", user()$displayName, "!")
})
<- dbConnect(
con ::databricks(),
odbchttpPath = Sys.getenv("DATABRICKS_PATH"),
authMech = 11,
auth_flow = 0,
auth_accesstoken = databricks_token(session)
)
$data <- render_gt({
output<- tbl(
data
con,in_catalog("samples", "nyctaxi", "trips")
|>
) head(10) |>
collect()
validate(need(nrow(data) > 0, "No data available"))
|>
data gt()
})
}
# call the databricks "current user" API to get
# information about the authenticated user.
<- function(session) {
databricks_user <- Sys.getenv("DATABRICKS_HOST")
host <- databricks_token(session)
token
<- file.path(
url paste0("https://", host),
"api/2.0/preview/scim/v2/Me",
fsep = "/"
)<- httr2::request(url) |>
resp ::req_auth_bearer_token(token) |>
httr2::req_retry(max_tries = 1) |>
httr2::req_perform()
httr2
validate(need(!resp_status(resp) == 403L, "Not authorized."))
validate(need(!resp_is_error(resp), resp))
<- httr2::resp_body_json(resp)
resp_body
resp_body
}
# obtain a databricks OAuth token.
# 1. if running on Posit Connect, exhanges Connect's user-session-token for the viewer's Databricks OAuth access token
# 2. if running on Posit Workbench, read the Databricks token from the workbench managed DATABRICKS_CONFIG_FILE
# 3. if running locally, read the Databricks token from the DATABRICKS_TOKEN environment var
<- function(session) {
databricks_token <- Sys.getenv("DATABRICKS_HOST")
host <- NULL
token
# if running on Connect
if (Sys.getenv("RSTUDIO_PRODUCT") == "CONNECT") {
# init Posit Connect API client
<- connect()
client # read the user-session-token header
<- session$request$HTTP_POSIT_CONNECT_USER_SESSION_TOKEN
user_session_token # exchange session token for viewer OAuth access token
<- get_oauth_credentials(client, user_session_token)
credentials <- credentials$access_token
token
# not running on Connect, so check for a .databrickscfg file (automatically set by workbench)
else if (Sys.getenv("DATABRICKS_CONFIG_FILE") != "") {
} <- get(".rs.api.getDatabricksToken")
getDatabricksToken <- getDatabricksToken(host)
token
# finally, look for a databricks token (must be set by the user when running locally)
else {
} <- Sys.getenv("DATABRICKS_TOKEN")
token
}
token
}
# start the Shiny app
shinyApp(ui = ui, server = server)
Running the app locally
Terminal
export DATABRICKS_HOST="<databricks-sql-warehouse-server-hostname>"
export DATABRICKS_PATH="<databricks-sql-warehouse-http-path>"
# TOKEN is only required when running the example locally
DATABRICKS_TOKEN="<databricks-token>" R -e "shiny::runApp()"