Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,55 @@ export("%>%")
export(HHMMSSmmm_to_ms)
export(assign_constants)
export(check_ssl_certs)
export(download_party_avatar)
export(download_session_asset)
export(download_session_assets_fr_df)
export(download_session_csv)
export(download_session_zip)
export(download_single_session_asset_fr_df)
export(download_video)
export(download_volume_zip)
export(get_asset_segment_range)
export(get_db_stats)
export(get_file_duration)
export(get_party_by_id)
export(get_folder_by_id)
export(get_institution_by_id)
export(get_permission_levels)
export(get_release_levels)
export(get_session_by_id)
export(get_session_by_name)
export(get_supported_file_types)
export(get_user_by_id)
export(get_volume_by_id)
export(is_institution)
export(is_person)
export(list_asset_formats)
export(list_authorized_investigators)
export(list_party_affiliates)
export(list_party_sponsors)
export(list_party_volumes)
export(list_folder_assets)
export(list_institution_affiliates)
export(list_session_activity)
export(list_session_assets)
export(list_sponsors)
export(list_user_affiliates)
export(list_user_history)
export(list_user_sponsors)
export(list_user_volumes)
export(list_users)
export(list_volume_activity)
export(list_volume_assets)
export(list_volume_excerpts)
export(list_volume_collaborators)
export(list_volume_folders)
export(list_volume_funding)
export(list_volume_info)
export(list_volume_links)
export(list_volume_owners)
export(list_volume_session_assets)
export(list_volume_sessions)
export(list_volume_tags)
export(list_volumes)
export(login_db)
export(logout_db)
export(make_default_request)
export(make_login_client)
export(search_for_funder)
export(search_for_keywords)
export(search_for_tags)
export(search_institutions)
export(search_users)
export(search_volumes)
export(whoami)
importFrom(lifecycle,deprecated)
importFrom(magrittr,"%>%")
Expand Down
109 changes: 36 additions & 73 deletions R/CONSTANTS.R
Original file line number Diff line number Diff line change
@@ -1,90 +1,53 @@
#' Load Package-wide Constants into Local Environment
#'
#'
DATABRARY_BASE_URL <- Sys.getenv("DATABRARY_BASE_URL", "https://api.stg-databrary.its.nyu.edu")

# Legacy endpoints (temporary until all functions migrated) -------------------

API_CONSTANTS <- "https://nyu.databrary.org/api/constants"

CREATE_SLOT <-
"https://nyu.databrary.org/api/volume/%s/slot"
CREATE_UPLOAD_FLOW <-
"https://nyu.databrary.org/api/volume/%s/upload"
CREATE_FILE_FROM_FLOW <-
"https://nyu.databrary.org/api/volume/%s/asset"

DATABRARY_API <- "https://nyu.databrary.org/api"
DOWNLOAD_FILE <-
"https://nyu.databrary.org/slot/%s/-/asset/%s/download"
DOWNLOAD_SESSION_ZIP <-
"https://nyu.databrary.org/volume/%s/slot/%s/zip/%s"
DOWNLOAD_VOLUME_ZIP <-
"https://nyu.databrary.org/volume/%s/zip/false"

GET_SESSIONS_IN_VOL <-
"https://nyu.databrary.org/api/volume/%s?records&containers=all"
GET_ACTIVITY_DATA <-
"https://nyu.databrary.org/api/activity"
GET_PARTY_BY_ID <-
"https://nyu.databrary.org/api/party/%s?parents&children&access"
GET_PARTY_NO_PARENTS_CHILDREN <- "https://nyu.databrary.org/api/party/%s"
GET_CONSTANTS <- "https://nyu.databrary.org/api/constants"
GET_PARTY_AVATAR <- "https://nyu.databrary.org/party/%s/avatar"

GET_SESSION_CSV <- "https://nyu.databrary.org/volume/%s/csv"
GET_SESSION_ACTIVITY <- "https://nyu.databrary.org/api/slot/%s/activity"
GET_SESSION_ZIP <- "https://nyu.databrary.org/volume/%s/slot/%s/zip/false"

GET_VOL_BY_ID <-
"https://nyu.databrary.org/api/volume/%s?access&citation&links&funding&top&tags&excerpts&comments&records&containers=all&metrics&state"
GET_VOLUME_FUNDING <- "https://nyu.databrary.org/api/volume/%s?funding=all"
GET_VOLUME_MINIMUM <- "https://nyu.databrary.org/api/volume/%s"
GET_VOLUME_LINKS <- "https://nyu.databrary.org/api/volume/%s?links=all"
GET_VOLUME_TAGS <- "https://nyu.databrary.org/api/volume/%s?tags=all"
GET_VOLUME_ACTIVITY <- "https://nyu.databrary.org/api/volume/%s/activity"
GET_VOLUME_ZIP <- "https://nyu.databrary.org/volume/%s/zip/false"
GET_VOLUME_EXCERPTS <- "https://nyu.databrary.org/api/volume/%s?excerpts=all"

GET_ASSET_BY_ID <- "https://nyu.databrary.org/api/asset/%s"
GET_ASSET_BY_VOLUME_SESSION_ID <-
"https://nyu.databrary.org/api/volume/%s/slot/%s/asset/%s"

# LOGIN <- "https://nyu.databrary.org/api/user/login"
# LOGOUT <- "https://nyu.databrary.org/api/user/logout"

QUERY_SLOT <-
"https://nyu.databrary.org/api/slot/%s/-?records&assets&excerpts&tags&comments"
QUERY_VOLUME_FUNDER <- "https://nyu.databrary.org/api/funder?query=%s"
QUERY_KEYWORDS <- "https://nyu.databrary.org/api/search?q=%s"
QUERY_TAGS <- "https://nyu.databrary.org/api/tags/%s"

SESSION_CSV <- "https://nyu.databrary.org/volume/%s/csv"

UPLOAD_CHUNK <- "https://nyu.databrary.org/api/upload"
UPDATE_SLOT <- "https://nyu.databrary.org/api/slot/%s"

# Authentication parameters
# USER_AGENT <-
# "databraryr (https://cran.r-project.org/package=databraryr)"
# KEYRING_SERVICE <- 'org.databrary.databraryr'
API_ACTIVITY_SUMMARY <- "/statistics/summary/"
API_GROUPED_FORMATS <- "/grouped-formats/"
API_USERS <- "/users/"
API_USER_DETAIL <- "/users/%s/"
API_USER_VOLUMES <- "/users/%s/volumes/"
API_USER_SPONSORSHIPS <- "/users/%s/sponsorships/"
API_USER_AFFILIATES <- "/users/%s/affiliates/"
API_USER_AVATAR <- "/users/%s/avatar/"
API_USERS_HISTORY <- "/users/%s/history/"
API_INSTITUTIONS <- "/institutions/%s/"
API_INSTITUTION_AFFILIATES <- "/institutions/%s/affiliates/"
API_INSTITUTION_AVATAR <- "/institutions/%s/avatar/"
API_VOLUMES <- "/volumes/"
API_VOLUME_DETAIL <- "/volumes/%s/"
API_VOLUME_TAGS <- "/volumes/%s/tags/"
API_VOLUME_LINKS <- "/volumes/%s/links/"
API_VOLUME_FUNDINGS <- "/volumes/%s/fundings/"
API_VOLUME_COLLABORATORS <- "/volumes/%s/collaborators/"
API_VOLUME_HISTORY <- "/volumes/%s/history/"
API_VOLUME_SESSIONS <- "/volumes/%s/sessions/"
API_VOLUME_FOLDERS <- "/volumes/%s/folders/"
API_SESSION_DETAIL <- "/volumes/%s/sessions/%s/"
API_SESSION_FILES <- "/volumes/%s/sessions/%s/files/"
API_SESSION_FILE_DETAIL <- "/volumes/%s/sessions/%s/files/%s/"
API_FILES_DOWNLOAD_LINK <- "/volumes/%s/sessions/%s/files/%s/download-link/"
API_SESSION_DOWNLOAD_LINK <- "/volumes/%s/sessions/%s/download-link/"
API_SESSION_CSV_DOWNLOAD_LINK <- "/volumes/%s/sessions/%s/csv-download-link/"
API_FOLDER_DETAIL <- "/volumes/%s/folders/%s/"
API_FOLDER_FILES <- "/volumes/%s/folders/%s/files/"
API_VOLUME_DOWNLOAD_LINK <- "/volumes/%s/download-link/"
API_VOLUME_CSV_DOWNLOAD_LINK <- "/volumes/%s/csv-download-link/"
API_SEARCH_VOLUMES <- "/search/volumes/"
API_SEARCH_USERS <- "/search/users/"
API_SEARCH_INSTITUTIONS <- "/search/institutions/"
API_FUNDERS <- "/funders/"

# httr2 request parameters
RETRY_LIMIT <- 3
RETRY_WAIT_TIME <- 1 # seconds
RETRY_BACKOFF <- 2 # exponential backoff
REQUEST_TIMEOUT <- 5 # seconds
REQUEST_TIMEOUT_VERY_LONG <- 600

# Base host -----------------------------------------------------------------

DATABRARY_BASE_URL <- Sys.getenv("DATABRARY_BASE_URL", "https://api.stg-databrary.its.nyu.edu")

# OAuth endpoints -------------------------------------------------------------

OAUTH_TOKEN_URL <- sprintf("%s/o/token/", DATABRARY_BASE_URL)
OAUTH_TEST_URL <- sprintf("%s/oauth2/test/", DATABRARY_BASE_URL)

# Authentication parameters ---------------------------------------------------

USER_AGENT <- Sys.getenv("USER_AGENT", "SRW$*Kxy2nYdyo4LozoGV#i6LvH/")
KEYRING_SERVICE <- 'org.databrary.databraryr'
176 changes: 176 additions & 0 deletions R/api_utils.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# Internal helpers for interacting with the Databrary Django API.

#' @noRd
ensure_leading_slash <- function(path) {
assertthat::assert_that(assertthat::is.string(path))
if (startsWith(path, "/")) {
path
} else {
paste0("/", path)
}
}

#' @noRd
build_query_params <- function(params) {
if (length(params) == 0) {
return(NULL)
}

keep <- !vapply(params, is.null, logical(1))
params <- params[keep]
lapply(params, function(value) {
if (is.logical(value)) {
# API expects lowercase true/false
tolower(as.character(value))
} else {
value
}
})
}

#' @noRd
perform_api_get <- function(path,
params = list(),
rq = NULL,
vb = FALSE,
parser = NULL,
normalize = TRUE,
response_type = c("json", "raw", "text")) {
response_type <- match.arg(response_type)

request <- rq
if (is.null(request)) {
request <- databraryr::make_default_request()
}

url <- paste0(DATABRARY_BASE_URL, ensure_leading_slash(path))
request <- httr2::req_url(request, url)

query <- build_query_params(params)
if (!is.null(query) && length(query) > 0) {
request <- do.call(httr2::req_url_query, c(list(request), query))
}

response <- tryCatch(
httr2::req_perform(request),
httr2_error = function(cnd) {
if (vb) {
message("Request failed for ", url, ": ", conditionMessage(cnd))
}
NULL
}
)

if (is.null(response)) {
return(NULL)
}

body <- switch(
response_type,
json = {
payload <- httr2::resp_body_json(response)
if (isTRUE(normalize)) {
payload <- snake_case_list(payload)
}
payload
},
raw = httr2::resp_body_raw(response),
text = httr2::resp_body_string(response)
)

if (!is.null(parser) && is.function(parser)) {
body <- parser(body)
}
body
}

#' @noRd
collect_paginated_get <- function(path,
params = list(),
rq = NULL,
vb = FALSE,
normalize = TRUE) {
next_url <- paste0(DATABRARY_BASE_URL, ensure_leading_slash(path))
first_iter <- TRUE
query <- build_query_params(params)

aggregated <- list()

while (!is.null(next_url)) {
request <- rq
if (is.null(request)) {
request <- databraryr::make_default_request(refresh = first_iter)
}

request <- httr2::req_url(request, next_url)
if (first_iter && !is.null(query) && length(query) > 0) {
request <- do.call(httr2::req_url_query, c(list(request), query))
}

resp <- tryCatch(
httr2::req_perform(request),
httr2_error = function(cnd) {
if (vb) {
message("Request failed for ", next_url, ": ", conditionMessage(cnd))
}
NULL
}
)

if (is.null(resp)) {
return(NULL)
}

body <- httr2::resp_body_json(resp)
if (isTRUE(normalize)) {
body <- snake_case_list(body)
}

page_results <- body$results
if (is.null(page_results)) {
if (is.list(body) && length(body) > 0 && (is.null(names(body)) || all(names(body) == ""))) {
page_results <- body
} else {
page_results <- list()
}
}

aggregated <- c(aggregated, page_results)

next_url <- body[["next"]]
if (!is.null(next_url) && !startsWith(next_url, "http")) {
next_url <- paste0(DATABRARY_BASE_URL, ensure_leading_slash(next_url))
}
if (!is.null(next_url)) {
next_url <- sub("^http://", "https://", next_url)
}

first_iter <- FALSE
}

aggregated
}

#' @noRd
camel_to_snake <- function(x) {
x <- gsub("(.)([A-Z][a-z]+)", "\\1_\\2", x)
tolower(gsub("([a-z0-9])([A-Z])", "\\1_\\2", x))
}

#' @noRd
snake_case_list <- function(obj) {
if (is.list(obj)) {
names_list <- names(obj)
if (!is.null(names_list)) {
names(obj) <- vapply(names_list, camel_to_snake, character(1))
}
obj <- lapply(obj, snake_case_list)
obj
} else if (is.vector(obj) && !is.null(names(obj))) {
names(obj) <- vapply(names(obj), camel_to_snake, character(1))
obj
} else {
obj
}
}

Loading