Nothing
#' Make HTTP GET Request
#'
#' Internal function to make authenticated GET requests to Lifebit Platform API.
#'
#' @param profile List. Profile configuration from load_profile().
#' @param endpoint Character. API endpoint path (without base URL).
#' @param query_params List. Query parameters to include in request.
#'
#' @return Parsed JSON response.
#' @keywords internal
http_get <- function(profile, endpoint, query_params = list()) {
# Build full URL
base_url <- profile$base_url
url <- paste0(base_url, endpoint)
# Add teamId to query params if not present
if (!"teamId" %in% names(query_params)) {
query_params$teamId <- profile$workspace_id
}
# Create request with specific options to avoid hanging
req <- httr2::request(url) |>
httr2::req_url_query(!!!query_params) |>
httr2::req_headers(
"apikey" = profile$apikey,
"Content-Type" = "application/json",
"Accept" = "application/json"
) |>
httr2::req_timeout(60) |>
httr2::req_options(
connecttimeout = 10,
tcp_keepalive = 1L,
tcp_keepidle = 120L,
tcp_keepintvl = 60L
) |>
httr2::req_retry(max_tries = 1) # No retries to avoid hanging
# Perform request
response <- tryCatch({
httr2::req_perform(req)
}, error = function(e) {
stop(sprintf("HTTP request failed: %s", e$message), call. = FALSE)
})
# Check status
status <- httr2::resp_status(response)
if (!(status %in% c(200, 202))) {
handle_api_error(response, endpoint)
}
# Parse and return response
return(parse_json_response(response))
}
#' Make HTTP POST Request
#'
#' Internal function to make authenticated POST requests to Lifebit Platform API.
#'
#' @param profile List. Profile configuration from load_profile().
#' @param endpoint Character. API endpoint path (without base URL).
#' @param body List. Request body to send as JSON.
#' @param query_params List. Query parameters to include in request.
#'
#' @return Parsed JSON response.
#' @keywords internal
http_post <- function(profile, endpoint, body = list(), query_params = list()) {
# Build full URL
base_url <- profile$base_url
url <- paste0(base_url, endpoint)
# Add teamId to query params if not present
if (!"teamId" %in% names(query_params)) {
query_params$teamId <- profile$workspace_id
}
# Create request with specific options to avoid hanging
req <- httr2::request(url) |>
httr2::req_url_query(!!!query_params) |>
httr2::req_headers(
"apikey" = profile$apikey,
"Content-Type" = "application/json",
"Accept" = "application/json"
) |>
httr2::req_body_json(body) |>
httr2::req_timeout(60) |>
httr2::req_options(
connecttimeout = 10,
tcp_keepalive = 1L,
tcp_keepidle = 120L,
tcp_keepintvl = 60L
) |>
httr2::req_retry(max_tries = 1) # No retries to avoid hanging
# Perform request
response <- tryCatch({
httr2::req_perform(req)
}, error = function(e) {
stop(sprintf("HTTP request failed: %s", e$message), call. = FALSE)
})
# Check status
status <- httr2::resp_status(response)
if (!(status %in% c(200, 202))) {
handle_api_error(response, endpoint)
}
# Parse and return response
return(parse_json_response(response))
}
#' Make HTTP Request with Retry
#'
#' Internal function to make HTTP requests with retry logic for transient failures.
#'
#' @param method Character. HTTP method ("GET" or "POST").
#' @param profile List. Profile configuration from load_profile().
#' @param endpoint Character. API endpoint path (without base URL).
#' @param body List. Request body (for POST requests).
#' @param query_params List. Query parameters.
#' @param max_retries Integer. Maximum number of retries (default: 3).
#' @param retry_delay Integer. Delay between retries in seconds (default: 2).
#'
#' @return Parsed JSON response.
#' @keywords internal
http_request_with_retry <- function(method,
profile,
endpoint,
body = list(),
query_params = list(),
max_retries = 3,
retry_delay = 2) {
last_error <- NULL
for (attempt in 1:max_retries) {
tryCatch({
if (method == "GET") {
return(http_get(profile, endpoint, query_params))
} else if (method == "POST") {
return(http_post(profile, endpoint, body, query_params))
} else {
stop(sprintf("Unsupported HTTP method: %s", method))
}
}, error = function(e) {
last_error <<- e
# Don't retry on authentication or authorization errors
if (grepl("401|403", e$message)) {
stop(e)
}
# Don't retry on client errors (4xx except 408)
if (grepl("40[024-9]", e$message)) {
stop(e)
}
# Retry on server errors (5xx) or network errors
if (attempt < max_retries) {
message(sprintf(
"Request failed (attempt %d/%d): %s\nRetrying in %d seconds...",
attempt,
max_retries,
e$message,
retry_delay
))
Sys.sleep(retry_delay)
}
})
}
# If we get here, all retries failed
stop(sprintf(
"Request failed after %d attempts. Last error: %s",
max_retries,
last_error$message
), call. = FALSE)
}
#' Build Query String
#'
#' Internal function to build URL query string from list of parameters.
#'
#' @param params List. Named list of query parameters.
#'
#' @return Character. URL-encoded query string.
#' @keywords internal
build_query_string <- function(params) {
if (length(params) == 0) {
return("")
}
# Filter out NULL and empty values
params <- params[!sapply(params, is.null)]
params <- params[sapply(params, function(x) length(x) > 0 && x != "")]
if (length(params) == 0) {
return("")
}
# Build query string
pairs <- mapply(function(name, value) {
if (length(value) > 1) {
# Handle array parameters (e.g., datasourceIds[])
paste(sapply(value, function(v) {
sprintf("%s=%s", utils::URLencode(name, reserved = TRUE), utils::URLencode(as.character(v), reserved = TRUE))
}), collapse = "&")
} else {
sprintf("%s=%s", utils::URLencode(name, reserved = TRUE), utils::URLencode(as.character(value), reserved = TRUE))
}
}, names(params), params, SIMPLIFY = FALSE, USE.NAMES = FALSE)
paste0("?", paste(unlist(pairs), collapse = "&"))
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.