R/auth.R

Defines functions kgl_auth

Documented in kgl_auth

#' Kaggle API authorization
#'
#' Authorizing access to Kaggle's API
#'
#' @param username Name associated with user's account at
#'   \href{https://www.kaggle.com}{Kaggle.com}.
#' @param key Key (a string of random letters and numbers) generated by Kaggle. Users can
#'   obtain or lookup their keys by signing into Kaggle and clicking on 'Account" or by
#'   substituting their username at kaggle.com/{username}/account.
#' @param creds_file Path to user's \code{kaggle.json} file. See @details for
#'   more information.
#'
#' @details
#' When Kaggle generates a key, it's sent to users as a
#' \code{kaggle.json} file, which is likely saved in a place like the default
#' Downloads folder or something. Users can (a) save the \code{kaggle.json}
#' file to a \code{.kaggle} directory in the user's machine's home folder
#' (i.e.,  \code{~/.kaggle/kaggle.json}), (b) specify the path to their
#' \code{kaggle.json} file using this \code{creds_file} argument, or (c)
#' save their \code{kaggle.json} file in their current working directory. The
#' third options (options c) is the least desirable as your working directory
#' will presumably change between sessions where you'd still want to have
#' authorized access to Kaggle's API. Either of the first two options would be
#' a good choice.
#'
#' Kaggle encourages users to save the "kaggle.json" credentials file in their
#' .kaggle file in their home directory (\code{~/.kaggle/kaggle.json}). If all
#' arguments are left NULL (their defaults), this function will look to see if
#' you computer has a \code{~/.kaggle/kaggle.json} file. If it can't find it
#' there, it'll look in the current working directory. If it finds the file,
#' it'll use it. Otherwise it'll look for environment variables, which it will
#' create and save for you manually the first time you enter your username/key
#' or path to your \code{kaggle.json} file.
#' @export
kgl_auth <- function(username = NULL, key = NULL, creds_file = NULL) {

  ## if all null, look for environment variables
  if (is.null(username) && is.null(key) && is.null(creds_file)) {
    if (file.exists("~/.kaggle/kaggle.json")) {
      creds_file <- "~/.kaggle/kaggle.json"
    } else if (file.exists("kaggle.json")) {
      creds_file <- "kaggle.json"
    }
  }

  if (is.null(username) && is.null(key) && is.null(creds_file)) {
    pat <- Sys.getenv("KAGGLE_PAT")
    if (!identical(pat, "")) {
      username <- sub("[/\\s,;].*", "", pat)
      key <- sub(".*[/\\s,;]", "", pat)
    } else {
      username <- Sys.getenv("KAGGLE_USERNAME")
      key <- Sys.getenv("KAGGLE_KEY")
    }
    if (identical(username, "") || identical(key, "")) {
      stop("Couldn't find environment variables. Please set\nKAGGLE_PAT=",
        "{username}/{key}\n# or\nKAGGLE_USERNAME={username}\nKAGGLE_KEY={key}")
    }

  ## alternatively, users can provide path to (or text of) creds_file
  } else if (!is.null(creds_file)) {

    ## read and parse kaggle.json creds file if it exists
    if (file.exists(creds_file)) {
      con <- file(creds_file)
      creds_file <- readLines(con, warn = FALSE, encoding = "UTF-8")
      close(con)

    ## if file doens't exist and if contents are NOT supplied as a string then STOP
    } else if (!grepl("username.*key", creds_file)) {
      stop("Kaggle credentials .json file not found. Provide path to file OR ",
        "enter your Kaggle 'username' and 'key' (from kaggle.com/{username}/account.",
        call. = FALSE)
    }

    ## parse the username and key
    username <- regmatches(creds_file, regexpr("(?<=username\":\")[^\"]+",
      creds_file, perl = TRUE))
    key <- regmatches(creds_file, regexpr("(?<=key\":\")[^\"]+",
      creds_file, perl = TRUE))

    ## validate username and key inputs
    stopifnot(length(username) == 1, is.atomic(username),
      length(key) == 1, is.character(key))

    ## set as store as env variable
    set_renv(KAGGLE_PAT = paste0(username, "/", key))

  } else {
    ## validate username and key inputs
    stopifnot(length(username) == 1, is.atomic(username),
      length(key) == 1, is.character(key))

    ## set as store as env variable
    set_renv(KAGGLE_PAT = paste0(username, "/", key))

    message("Your Kaggle key has been recorded for this session and saved as `KAGGLE_PAT`\n",
      "  environment variable for future sessions.")
  }

  ## return basic http authorization method (with kaggle-generated key as password)
  httr::authenticate(username, key)
}
mkearney/kaggler documentation built on May 17, 2019, 1:58 p.m.