From 1308a467cfb9ada43a68d325c02d5332f3e5b686 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 10:25:01 -0500 Subject: [PATCH 01/14] Increment version number to 0.5.3.9000 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 60d2ac2..f6700c4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: draft.kings Type: Package Title: Draft Kings API Wrapper and Optimization -Version: 0.5.3 +Version: 0.5.3.9000 Author: Giovanni Colitti Maintainer: Giovanni Colitti Description: Fetch data from DraftKings using the provided API and perform lineup optimization. From 95c6dfecf26c70b3b0b343e09de4d650b42113d2 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 10:24:36 -0500 Subject: [PATCH 02/14] Update roxygen version --- DESCRIPTION | 2 +- man/dk_req_perform.Rd | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f6700c4..239e196 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -24,7 +24,7 @@ Imports: tidyjson, tidyr, utils -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.2 Suggests: devtools, diffviewer, diff --git a/man/dk_req_perform.Rd b/man/dk_req_perform.Rd index 47685dd..47813db 100644 --- a/man/dk_req_perform.Rd +++ b/man/dk_req_perform.Rd @@ -16,16 +16,16 @@ dk_req_perform( \arguments{ \item{req}{A \link[httr2]{request}.} -\item{path}{Optionally, path to save body of request. This is useful for -large responses since it avoids storing the response in memory.} +\item{path}{Optionally, path to save body of the response. This is useful +for large responses since it avoids storing the response in memory.} \item{verbosity}{How much information to print? This is a wrapper -around \code{req_verbose()} that uses an integer to control verbosity: +around \code{\link[httr2:req_verbose]{req_verbose()}} that uses an integer to control verbosity: \itemize{ -\item 0: no output -\item 1: show headers -\item 2: show headers and bodies -\item 3: show headers, bodies, and curl status messages. +\item \code{0}: no output +\item \code{1}: show headers +\item \code{2}: show headers and bodies +\item \code{3}: show headers, bodies, and curl status messages. } Use \code{\link[httr2:with_verbosity]{with_verbosity()}} to control the verbosity of requests that From 97dd8d1ecf5700c5a3e16fa38f7b93ac9e272881 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 11:55:29 -0500 Subject: [PATCH 03/14] Remove dk_get() and dk_multi_get() --- R/dk_get.R | 227 -------------- R/dk_multi_get.R | 287 ------------------ .../dk_get/url/contests/67116261-7315b4.json | 70 ----- .../dk_get/url/contests/67260593-7315b4.json | 72 ----- .../url/leaderboards/67116261-2b15c9.json | 48 --- .../url/leaderboards/67260593-2b15c9.json | 69 ----- tests/testthat/test-dk_get.R | 53 ---- tests/testthat/test-dk_multi_get.R | 112 ------- 8 files changed, 938 deletions(-) delete mode 100644 R/dk_get.R delete mode 100644 R/dk_multi_get.R delete mode 100644 tests/testthat/dk_get/url/contests/67116261-7315b4.json delete mode 100644 tests/testthat/dk_get/url/contests/67260593-7315b4.json delete mode 100644 tests/testthat/dk_get/url/leaderboards/67116261-2b15c9.json delete mode 100644 tests/testthat/dk_get/url/leaderboards/67260593-2b15c9.json delete mode 100644 tests/testthat/test-dk_get.R delete mode 100644 tests/testthat/test-dk_multi_get.R diff --git a/R/dk_get.R b/R/dk_get.R deleted file mode 100644 index 24c17e1..0000000 --- a/R/dk_get.R +++ /dev/null @@ -1,227 +0,0 @@ -#' Get Draft Kings Data -#' -#' Fetch DraftKings data -#' in parallel using Packet Stream proxies by default. -#' -#' @inheritParams furrr::future_map -#' @inheritParams dk_request_process -#' @param func A function from the `draft.kings` package. -#' @param keys This is passed as the first argument to `func`. -#' @param retry_options List of arguments passed to `httr2::req_retry()`. -#' If `NULL` (the default), `max_tries` is set to 5 and these status codes are considered -#' transient: 429, 500, 503, 408, 400. -#' @param proxy_args List of arguments to `httr2::req_proxy`. -#' If `NULL` (the default), this argument will look for environmental variables -#' related to PacketStream. See details section for which environmental variables should -#' be set. -#' @param furrr_options Options passed to `furrr::furrr_options`. -#' If `NULL` (the default), then will use `seed` and `stdout` to `TRUE`, and ensure -#' required packages are passed to the workers. -#' @param report_time Should the time it took the function to complete be reported? -#' @param ... Other arguments passed to underlying `draft.kings` function (`func`) -#' -#' @details -#' -#' If `proxy_args` is `TRUE`, then the following environmental variables should be set: -#' -#' PACKET_STREAM_URL -#' PACKET_STREAM_PORT -#' PACKET_STREAM_USER -#' PACKET_STREAM_PASS -#' -#' @export -dk_get <- function(func, - keys, - output = c("all", "cleaned_json", "json", "response", "request"), - retry_options = NULL, - proxy_args = NULL, - report_time = TRUE, - .progress = TRUE, - furrr_options = NULL, - ...) { - - output <- rlang::arg_match(output) - - # Set retry options if not passed - if (is.null(retry_options)) { - - is_transient <- function(resp) { - httr2::resp_status(resp) %in% c(429, 500, 503, 408, 400) - } - # Don't include caller function objects in environment - # this reduces size of resulting response/request object - environment(is_transient) <- new.env(parent = baseenv()) - - retry_options <- list( - max_tries = 5, - is_transient = is_transient - ) - } - - # Set proxy args if not passed - if (is.null(proxy_args)) { - proxy_args <- list( - url = Sys.getenv('PACKET_STREAM_URL'), - port = as.numeric(Sys.getenv('PACKET_STREAM_PORT')), - username = Sys.getenv('PACKET_STREAM_USER'), - password = paste0(Sys.getenv('PACKET_STREAM_PASS'), "_country-UnitedStates"), - auth = "basic" - ) - } - - # Set options which enable proxy IP rotation - # See: https://stackoverflow.com/a/76135690/9489566 - dots_list <- list(...) - if (!"curl_options" %in% names(dots_list)) { - curl_options <- list(forbid_reuse = TRUE) - } - - if (!"headers" %in% names(dots_list)) { - headers <- list(Connection = "close") - } - - if (is.null(furrr_options)) { - furrr_options <- list(stdout = TRUE, - seed = TRUE, - packages = c("dplyr", "draft.kings", "cli")) - } - - start_time <- Sys.time() - - out <- withCallingHandlers( - # Need suppressPackageStartupMessages() because furrr_options(packages = ...) - expr = suppressPackageStartupMessages(furrr::future_map_dfr( - .progress = .progress, - .options = do.call(furrr::furrr_options, furrr_options), - keys, - function(.key) { - - resp <- NULL - - resp <- tryCatch( - expr = { - - out <- func( - .key, - output = if (output == "all") "response" else output, - retry_options = retry_options, - proxy_args = proxy_args, - headers = headers, - curl_options = curl_options, - ... - ) - - if (output == "all") { - - out <- dplyr::tibble( - key = .key, - request = list(httr2::last_request()), - response = list(out), - json = list(httr2::resp_body_json(out)), - cleaned_json = list(draft.kings::dk_resp_parse(out)), - status = out$status_code, - error_message = as.character(NA), - error_output = list(NULL) - ) - - # Only return request - } else if (output == "request") { - - out <- dplyr::tibble( - key = .key, - !!output := list(out) - ) - - } else { - - out <- dplyr::tibble( - key = .key, - !!output := list(out), - status = out$status_code, - error_message = as.character(NA), - error_output = list(NULL) - ) - - } - - out - - }, - - error = function(error) { - - error - - } - - ) - - if (inherits(resp, "error")) { - - if (output == "all") { - - out <- dplyr::tibble( - key = .key, - request = list(httr2::last_request()), - response = list(resp$resp), - error_output = list(resp), - error_message = resp$message, - status = resp$resp$status - ) - - } else if (output == "request") { - - out <- dplyr::tibble( - key = .key, - request = list(httr2::last_request()), - response = list(resp$resp), - error_output = list(resp), - error_message = resp$message, - status = resp$resp$status - ) - - } else { - - out <- dplyr::tibble( - key = .key, - response = list(resp$resp), - error_output = list(resp), - error_message = resp$message, - status = resp$resp$status - ) - - } - - } - - - out - - } - )), - warning = function(w) { - - } - ) - - if ("status" %in% colnames(out)) { - - status_200_count <- sum(out$status == 200, na.rm = TRUE) - total <- length(out$status) - non_200_status_count <- total - status_200_count - pct_total <- round(non_200_status_count / total * 100, 1) - - if (non_200_status_count > 0) { - - cli::cli_warn( - "{non_200_status_count} of {total} request{?s} ({pct_total}%) did not have a 200 status code" - ) - } - - } - - if (report_time) pretty_duration(start_time, prefix = "Total time") - - out - -} diff --git a/R/dk_multi_get.R b/R/dk_multi_get.R deleted file mode 100644 index ad2fc23..0000000 --- a/R/dk_multi_get.R +++ /dev/null @@ -1,287 +0,0 @@ - -#' Perform multiple requests in parallel -#' -#' @description `multi_req_perform2` performs multiple HTTP requests concurrently -#' and optionally retries failed attempts. -#' -#' @inheritParams httr2::multi_req_perform -#' -#' @param retry_sleep A numeric value indicating the number of seconds to sleep -#' after performing the requests. If NULL or negative, no sleep is performed. -#' @param max_tries Maximum number of retry attempts for responses that are flagged as -#' transient with the `is_transient` function. By default, will retry 1 time. -#' @param is_transient A predicate function that takes a single argument (the response) and -#' returns TRUE or FALSE specifying whether or not the response represents a transient error. -#' By default, requests with a 429, 503, or 403 status code are treated as transient, -#' as well as requests that completely failed and returned no status code. -#' @param verbose Should messages related to retry logic be reported? -#' @param ... Other arguments passed to [httr2::multi_req_perform()] -#' -#' @details -#' This function is a wrapper around [httr2::multi_req_perform()] that allows for -#' the introduction of retry logic if some requests meet user-defined criteria. -#' This can be useful for sending many requests that are likely to encounter transient -#' errors that can be resolved with additional attempts. -#' -#' @return A list of responses from [httr2::multi_req_perform()]. -#' -#' @examples -#' \dontrun{ -#' req_list <- list( -#' httr2::request("http://httpbin.org/get"), -#' httr2::request("http://httpbin.org/get") -#' ) -#' responses <- multi_req_perform2(req_list, retry_sleep = 2) -#' } -#' -#' @keywords internal -#' -multi_req_perform2 <- function(reqs, max_tries = 1, retry_sleep = 3, is_transient = NULL, - paths = NULL, verbose = FALSE, ...) { - - if (!is.numeric(retry_sleep) || retry_sleep < 0) { - stop("`retry_sleep` should be a non-negative numeric value.") - } - - if (!is.numeric(max_tries) || max_tries <= 0) { - stop("`max_tries` should be a positive integer.") - } - - if (!is.null(is_transient) && !is.function(is_transient)) { - stop("`is_transient` should be a function.") - } - - if (is.null(is_transient)) { - is_transient <- function(resp) { - is.null(resp) || "httr2_failed" %in% class(resp) || resp$status %in% c(429, 503, 403) - } - # Don't include caller function objects in environment - # this reduces size of resulting response - environment(is_transient) <- new.env(parent = baseenv()) - } - - out <- httr2::multi_req_perform(reqs, paths = paths, ...) - - try_count <- 1 - - # Check if any requests need to be retried - retry_indices <- sapply(out, function(resp) isTRUE(is_transient(resp))) - success <- all(!retry_indices) - - while (!success && try_count <= max_tries) { - - if (verbose) { - cli::cli_inform( - paste( - "Retrying {sum(retry_indices)} unsuccessful request{?s}.", - "Attempt {try_count} of {max_tries}" - ) - ) - } - - # Sleep only if not the first try - if (try_count > 1 && retry_sleep > 0) { - Sys.sleep(retry_sleep) - } - - # Prepare the requests that need to be retried - retry_reqs <- reqs[retry_indices] - - # Perform the requests - retry_out <- httr2::multi_req_perform(retry_reqs, paths = paths[retry_indices], ...) - - # Update the original output with the new results - out[retry_indices] <- retry_out - - try_count <- try_count + 1 - - # Check if any requests need to be retried - retry_indices <- sapply(out, function(resp) isTRUE(is_transient(resp))) - success <- all(!retry_indices) - } - - if (!success) { - # Warn when max_tries were reached but some requests still failed - failed_pct <- paste0(round(100 * sum(retry_indices) / length(out)), "%") - cli::cli_warn( - paste( - "{sum(retry_indices)} of {length(out)} request{?s} ({failed_pct})", - "failed after {max_tries} attempts." - ) - ) - } - - out -} - - -#' Chunk a vector into a specified number of chunks or a specified chunk size -#' -#' @param x A vector or other R object that can be split. -#' @param n_chunks An optional integer indicating the desired number of chunks. -#' @param chunk_size An optional integer indicating the desired number of elements per chunk. -#' -#' @details -#' This function splits the input `x` into multiple chunks based on the specified -#' `n_chunks` or `chunk_size`. If both are provided, `chunk_size` takes precedence -#' and `n_chunks` is ignored with a warning. If neither is provided, the function -#' will stop with an error. The function returns a list of chunks. -#' -#' @return A list of chunks. -#' -#' @examples -#' \dontrun{ -#' vec <- 1:10 -#' chunk(vec, chunk_size = 3) -#' chunk(vec, n_chunks = 3) -#' } -#' -#' @keywords internal -#' -chunk <- function(x, n_chunks = NULL, chunk_size = NULL) { - - if (is.null(n_chunks) && is.null(chunk_size)) { - stop("Both `n_chunks` and `chunk_size` cannot be NULL.") - } - - if (!is.null(n_chunks) && !is.null(chunk_size)) { - warning( - paste("Both `n_chunks` and `chunk_size` were specified.", - "Only `chunk_size` will be used.") - ) - n_chunks <- NULL - } - - if (!is.null(chunk_size)) { - - if (chunk_size <= 0) { - stop("`chunk_size` must be a positive integer.") - } - - # Warn if chunk_size is greater than the length of x - if (chunk_size > length(x)) { - warning( - paste("`chunk_size` is greater than the length of `x`.", - "This will result in fewer chunks than expected.") - ) - } - - groups <- ceiling(seq_along(x) / chunk_size) - out <- split(x, groups) - - } else { - - if (n_chunks <= 0) { - stop("`n_chunks` must be a positive integer.") - } - - # Warn if n_chunks is greater than the length of x - if (n_chunks > length(x)) { - warning( - paste("`n_chunks` is greater than the length of `x`.", - "This will result in fewer chunks than expected.") - ) - n_chunks <- length(x) - } - - # Don't try to break x if n_chunks is set to 1 - if (n_chunks == 1) { - out <- list(x) - } else { - groups <- cut(seq_along(x), n_chunks, labels = FALSE) - out <- split(x, groups) - } - - } - - out -} - - -#' Get Draft Kings Data in Parallel -#' -#' Fetch DraftKings data in parallel using `httr2::multi_req_perform()` -#' with retry logic and in batches. -#' -#' @inheritParams dk_request_process -#' @inheritParams chunk -#' @inheritParams multi_req_perform2 -#' @inheritParams purrr::map -#' -#' @param chunk_size,n_chunks Arguments passed to [chunk()]. -#' By default, `reqs` is not batched into chunks. -#' @param batch_sleep Delay in seconds between batches defined by `chunk_size` or `n_chunks`. -#' @param retry_sleep Delay in seconds between retries. See [multi_req_perform2()] for details. -#' @param report_time Should the time it took the function to complete be reported? -#' @param ... Other arguments passed to [multi_req_perform2()]. -#' -#' @return A list of `httr2` response objects returned by [httr2::multi_req_perform()] -#' -#' @export -dk_multi_get <- function(reqs, - paths = NULL, - chunk_size = NULL, - n_chunks = NULL, - batch_sleep = 3, - retry_sleep = 3, - report_time = TRUE, - .progress = TRUE, - ...) { - - if (!is.numeric(batch_sleep) || batch_sleep < 0) { - stop(sprintf("`batch_sleep` should be a non-negative numeric value. Received: %s", batch_sleep)) - } - - if (!is.numeric(retry_sleep) || retry_sleep < 0) { - stop(sprintf("`retry_sleep` should be a non-negative numeric value. Received: %s", retry_sleep)) - } - - # Check if the length of `paths` matches the length of `reqs` - if (!is.null(paths) && length(paths) != length(reqs)) { - stop(sprintf("The length of `paths` should match the length of `reqs`. Length of `paths`: %s, Length of `reqs`: %s", length(paths), length(reqs))) - } - - # Don't use batching if neither chunk_size or n_chunks are passed - if (is.null(chunk_size) && is.null(n_chunks)) { - n_chunks <- 1 - } - - start_time <- Sys.time() - - request_batches <- chunk(reqs, - n_chunks = n_chunks, - chunk_size = chunk_size) - - if (!is.null(paths)) { - path_batches <- chunk(paths, - n_chunks = n_chunks, - chunk_size = chunk_size) - - } else { - path_batches <- list(NULL) - } - - # Loop over batches - responses_lst <- purrr::map2( - .progress = .progress, - request_batches, - path_batches, - \(reqs, paths) { - - out <- multi_req_perform2(reqs, retry_sleep = retry_sleep, paths = paths, ...) - - # Only sleep if there is more than one batch - if (length(request_batches) > 1) Sys.sleep(batch_sleep) - - out - } - ) - - # Combine batches of responses into a single list - out <- do.call("c", responses_lst) - - if (report_time) pretty_duration(start_time, prefix = "Total time") - - out - -} diff --git a/tests/testthat/dk_get/url/contests/67116261-7315b4.json b/tests/testthat/dk_get/url/contests/67116261-7315b4.json deleted file mode 100644 index 24c5014..0000000 --- a/tests/testthat/dk_get/url/contests/67116261-7315b4.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "contestDetail": { - "contestSummary": "This 100-player contest features $0.00 in total prizes and pays out the top 1 finishing positions. First place wins $0.00.", - "payoutSummary": [ - { - "minPosition": 1, - "maxPosition": 1, - "tierPayoutDescriptions": { - "Cash": "$0.00" - } - } - ], - "PayoutDescription": "$0", - "IsCashPrizeOnly": true, - "scoringStyleId": 1, - "contestStateDetail": "Completed", - "includesPastSeasonCollectibles ": false, - "sport": "NBA", - "isGuaranteed": true, - "isPrivate": true, - "isResizable": false, - "wasResized": false, - "exclusions": [ - "AllContests", - "ContestTypeBlackList-70", - "GameTypeBlackList-70", - "SportsBlackList-0" - ], - "acceptedTickets": [ - - ], - "payoutDescriptions": { - - }, - "payoutDescriptionMetadata": [ - - ], - "fppAward": 0, - "sortOrder": -1001, - "filters": [ - - ], - "contestStartTime": "2019-01-01T01:00:00.0000000Z", - "gameTypeId": 70, - "ticketOnlyEntry": false, - "gameSetKey": "AFCDDE7381D0184FDD5C4B5F75B5DA60", - "contestKey": "67116261", - "name": "NBA Tester (Night)", - "draftGroupId": 23802, - "playTypeId": 41134, - "entries": 1, - "maximumEntries": 100, - "maximumEntriesPerUser": 1, - "entryFee": 0, - "totalPayouts": 0, - "contestState": "Completed", - "attributes": { - "IsGuranteed": "true", - "LobbyClass": "icon-lightning-bolt", - "IsInternal": "true", - "Allow Pregeneration": "true", - "Is NonRevenue": "true", - "IsVideoGated": "true", - "Ignore EntryFeeMin": "true" - } - }, - "errorStatus": { - - } -} diff --git a/tests/testthat/dk_get/url/contests/67260593-7315b4.json b/tests/testthat/dk_get/url/contests/67260593-7315b4.json deleted file mode 100644 index dac405b..0000000 --- a/tests/testthat/dk_get/url/contests/67260593-7315b4.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "contestDetail": { - "contestSummary": "This 2-player contest features $0.00 in total prizes and pays out the top 1 finishing positions. First place wins $0.00.", - "payoutSummary": [ - { - "minPosition": 1, - "maxPosition": 1, - "tierPayoutDescriptions": { - "Cash": "$0.00" - } - } - ], - "PayoutDescription": "$0", - "IsCashPrizeOnly": true, - "scoringStyleId": 1, - "contestStateDetail": "Completed", - "includesPastSeasonCollectibles ": false, - "sport": "NBA", - "isGuaranteed": false, - "isPrivate": false, - "isResizable": false, - "wasResized": false, - "exclusions": [ - "AllContests", - "ContestTypeBlackList-70", - "GameTypeBlackList-70", - "SportsBlackList-0", - "PublicContest" - ], - "acceptedTickets": [ - - ], - "payoutDescriptions": { - - }, - "payoutDescriptionMetadata": [ - - ], - "fppAward": 0, - "ownerUserKey": "608452", - "sortOrder": 3368600, - "filters": [ - - ], - "contestStartTime": "2019-01-01T00:00:00.0000000Z", - "gameTypeId": 70, - "ticketOnlyEntry": false, - "gameSetKey": "C48201D5C172CABD821457F07B05991B", - "contestKey": "67260593", - "name": "NBA FREE", - "draftGroupId": 23801, - "playTypeId": 2114, - "entries": 2, - "maximumEntries": 2, - "maximumEntriesPerUser": 1, - "entryFee": 0, - "totalPayouts": 0, - "contestState": "Completed", - "attributes": { - "Multi Match Limit By User": "608452", - "Head to Head Opponent Name": "LoganWayne97", - "On Demand Creation": "true", - "Is H2H": "true", - "DC Prize Structure Type": "8", - "IsVideoGated": "true", - "Ignore EntryFeeMin": "true" - } - }, - "errorStatus": { - - } -} diff --git a/tests/testthat/dk_get/url/leaderboards/67116261-2b15c9.json b/tests/testthat/dk_get/url/leaderboards/67116261-2b15c9.json deleted file mode 100644 index 3ebf127..0000000 --- a/tests/testthat/dk_get/url/leaderboards/67116261-2b15c9.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "href": "/scores/v1/contests/67116261/", - "contestKey": "67116261", - "leader": { - "draftGroupId": 23802, - "contestKey": "67116261", - "entryKey": "1350511114", - "lineupId": -1, - "userName": "dk-rdoherty", - "userKey": "6727722", - "userEntryCount": 1, - "userEntryIndex": 1, - "timeRemaining": 0, - "timeRemainingUnit": "PMR", - "maxTimeRemaining": 384, - "timeRemainingOpponent": 0, - "rank": 1, - "fantasyPoints": 228.75, - "fantasyPointsOpponent": 228.75, - "userNameOpponent": "dk-rdoherty", - "numberTicketsWon": 0, - "ticketsValue": 0, - "winningValue": 0 - }, - "leaderBoard": [ - { - "draftGroupId": 23802, - "contestKey": "67116261", - "entryKey": "1350511114", - "lineupId": -1, - "userName": "dk-rdoherty", - "userKey": "6727722", - "userEntryCount": 1, - "userEntryIndex": 1, - "timeRemaining": 0, - "timeRemainingUnit": "PMR", - "maxTimeRemaining": 384, - "timeRemainingOpponent": 0, - "rank": 1, - "fantasyPoints": 228.75, - "fantasyPointsOpponent": 228.75, - "userNameOpponent": "dk-rdoherty", - "numberTicketsWon": 0, - "ticketsValue": 0, - "winningValue": 0 - } - ] -} diff --git a/tests/testthat/dk_get/url/leaderboards/67260593-2b15c9.json b/tests/testthat/dk_get/url/leaderboards/67260593-2b15c9.json deleted file mode 100644 index e38c1cb..0000000 --- a/tests/testthat/dk_get/url/leaderboards/67260593-2b15c9.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "href": "/scores/v1/contests/67260593/", - "contestKey": "67260593", - "leader": { - "draftGroupId": 23801, - "contestKey": "67260593", - "entryKey": "1350468971", - "lineupId": -1, - "userName": "artman1968", - "userKey": "608452", - "userEntryCount": 1, - "userEntryIndex": 1, - "timeRemaining": 0, - "timeRemainingUnit": "PMR", - "maxTimeRemaining": 384, - "timeRemainingOpponent": 0, - "rank": 1, - "fantasyPoints": 244.25, - "fantasyPointsOpponent": 204.75, - "userNameOpponent": "LoganWayne97", - "numberTicketsWon": 0, - "ticketsValue": 0, - "winningValue": 0 - }, - "leaderBoard": [ - { - "draftGroupId": 23801, - "contestKey": "67260593", - "entryKey": "1350468971", - "lineupId": -1, - "userName": "artman1968", - "userKey": "608452", - "userEntryCount": 1, - "userEntryIndex": 1, - "timeRemaining": 0, - "timeRemainingUnit": "PMR", - "maxTimeRemaining": 384, - "timeRemainingOpponent": 0, - "rank": 1, - "fantasyPoints": 244.25, - "fantasyPointsOpponent": 204.75, - "userNameOpponent": "LoganWayne97", - "numberTicketsWon": 0, - "ticketsValue": 0, - "winningValue": 0 - }, - { - "draftGroupId": 23801, - "contestKey": "67260593", - "entryKey": "1351541454", - "lineupId": -1, - "userName": "LoganWayne97", - "userKey": "10683029", - "userEntryCount": 1, - "userEntryIndex": 1, - "timeRemaining": 0, - "timeRemainingUnit": "PMR", - "maxTimeRemaining": 384, - "timeRemainingOpponent": 0, - "rank": 2, - "fantasyPoints": 204.75, - "fantasyPointsOpponent": 244.25, - "userNameOpponent": "artman1968", - "numberTicketsWon": 0, - "ticketsValue": 0, - "winningValue": 0 - } - ] -} diff --git a/tests/testthat/test-dk_get.R b/tests/testthat/test-dk_get.R deleted file mode 100644 index e56dd9d..0000000 --- a/tests/testthat/test-dk_get.R +++ /dev/null @@ -1,53 +0,0 @@ - -httptest2::with_mock_dir("dk_get", { - - test_that("dk_get() works with dk_get_contest_info", { - d <- dk_get(dk_get_contest_info, c(67260593, 67116261)) - - testthat::expect_equal( - names(d), - c("key", "request", "response", "json", "cleaned_json", - "status", "error_message", "error_output") - ) - - testthat::expect_s3_class(d, "tbl_df") - - testthat::expect_true(all(d$status == 200)) - - }) - - test_that("dk_get() works with dk_get_leaderboard", { - d <- dk_get(dk_get_leaderboard, c(67260593, 67116261)) - - testthat::expect_equal( - names(d), - c("key", "request", "response", "json", "cleaned_json", - "status", "error_message", "error_output") - ) - - testthat::expect_s3_class(d, "tbl_df") - - testthat::expect_true(all(d$status == 200)) - - }) - - test_that("dk_get() works with invalid contest keys", { - testthat::expect_warning( - d <- dk_get(dk_get_leaderboard, c(67260593, 67116261, 5), - retry_options = list(max_tries = 1)), - "did not have a 200 status code" - ) - - testthat::expect_equal( - names(d), - c("key", "request", "response", "json", "cleaned_json", - "status", "error_message", "error_output") - ) - - testthat::expect_s3_class(d, "tbl_df") - - }) - -}) - - diff --git a/tests/testthat/test-dk_multi_get.R b/tests/testthat/test-dk_multi_get.R deleted file mode 100644 index 8781d43..0000000 --- a/tests/testthat/test-dk_multi_get.R +++ /dev/null @@ -1,112 +0,0 @@ - -# Tests for chunk() ---- -# Test for correct chunking with chunk_size -test_that("chunk splits correctly with chunk_size", { - vec <- 1:10 - result <- chunk(vec, chunk_size = 3) - expect_equal(length(result), 4) - expect_equal(result[[1]], 1:3) - expect_equal(result[[4]], 10) -}) - -# Test for correct chunking with n_chunks -test_that("chunk splits correctly with n_chunks", { - vec <- 1:10 - result <- chunk(vec, n_chunks = 3) - expect_equal(length(result), 3) -}) - -# Test for warning when chunk_size is greater than length of x -test_that("warning when chunk_size is greater than length of x", { - vec <- 1:5 - expect_warning(chunk(vec, chunk_size = 10)) -}) - -# Test for warning when n_chunks is greater than length of x -test_that("warning when n_chunks is greater than length of x", { - vec <- 1:5 - expect_warning(chunk(vec, n_chunks = 10)) -}) - -# Test for error when both n_chunks and chunk_size are NULL -test_that("error when both n_chunks and chunk_size are NULL", { - vec <- 1:10 - expect_error(chunk(vec)) -}) - -# Test for error when chunk_size is not a positive integer -test_that("error when chunk_size is not a positive integer", { - vec <- 1:10 - expect_error(chunk(vec, chunk_size = -1)) -}) - -# Test for error when n_chunks is not a positive integer -test_that("error when n_chunks is not a positive integer", { - vec <- 1:10 - expect_error(chunk(vec, n_chunks = -1)) -}) - -# Tests for dk_multi_get() ---- - -httptest2::with_mock_dir("dk_multi_get", { - # Test for successful request - test_that("successful request returns correct response", { - reqs <- list( - httr2::request("https://httpbin.org/get") - ) - reqs <- rep(reqs, 5) - result <- dk_multi_get(reqs) - expect_equal(length(result), 5) - expect_true(all(sapply(result, \(x) x$status == 200))) - }) - - # Test for handling of batch_sleep and retry_sleep - test_that("batch_sleep and retry_sleep are handled correctly", { - reqs <- list( - httr2::request("https://httpbin.org/status/403"), - httr2::request("https://httpbin.org/status/403") - ) - batch_sleep <- 2 - retry_sleep <- 1 - n_chunks <- 2 - max_tries <- 2 - start_time <- Sys.time() - # Suppress warnings because retries will fail both times - result <- suppressWarnings( - dk_multi_get(reqs, batch_sleep = batch_sleep, retry_sleep = retry_sleep, - n_chunks = n_chunks, max_tries = max_tries, - .progress = FALSE) - ) - end_time <- Sys.time() - - # Expect 5s delay for sleep between batches and - # 4s delay for retrying each batch twice (1s delay per try set by retry_sleep) - expected_time <- batch_sleep + retry_sleep * n_chunks * max_tries - time_diff <- as.numeric(difftime(end_time, start_time, units = "secs")) - - # Added tolerance to account for the time it actually takes to perform requests - # which should be minimal - expect_equal(time_diff, expected_time, tolerance = 1) - expect_equal(length(result), 2) - }) -}) - - -# Test for handling of invalid retry_sleep -test_that("invalid retry_sleep value throws an error", { - reqs <- list(httr2::request("https://httpbin.org/get")) - expect_error(dk_multi_get(reqs, retry_sleep = -1)) -}) - -# Test for handling invalid batch_sleep -test_that("invalid batch_sleep value throws an error", { - reqs <- list(httr2::request("https://httpbin.org/get")) - expect_error(dk_multi_get(reqs, batch_sleep = -1)) -}) - -# Test for handling mismatched lengths of reqs and paths -test_that("mismatched lengths of reqs and paths throws an error", { - reqs <- list(httr2::request("https://httpbin.org/get"), httr2::request("https://httpbin.org/get")) - paths <- list("path1") - expect_error(dk_multi_get(reqs, paths = paths)) -}) From ee00265a2b20a23540aaff1ad951dbcf928de336 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 11:59:00 -0500 Subject: [PATCH 04/14] Rename dk_request* to dk_req* and dk_response* to dk_resp* --- R/api-parse.R | 4 ++-- R/competition.R | 6 +++--- R/contest.R | 32 ++++++++++++++++---------------- R/draftgroup.R | 42 +++++++++++++++++++++--------------------- R/httr2-wrappers.R | 7 +++++++ R/leaderboard.R | 16 ++++++++-------- R/req.R | 4 ++-- R/sports.R | 8 ++++---- R/utils.R | 7 ++++--- 9 files changed, 67 insertions(+), 59 deletions(-) diff --git a/R/api-parse.R b/R/api-parse.R index bb082e6..604a0aa 100644 --- a/R/api-parse.R +++ b/R/api-parse.R @@ -43,7 +43,6 @@ extract_unix_timestamp <- function(x) { #' Parse Response JSON #' #' @inheritParams httr2::resp_body_json -#' #' @export dk_resp_parse <- function(resp) { UseMethod("dk_resp_parse") @@ -207,7 +206,8 @@ dk_resp_parse.lobby_game_types_resp <- function(resp) { } #### Draftgroup ------------------------------------------------------------------------------------ - +#' @method dk_resp_parse draft_group_resp +#' @export dk_resp_parse.draft_group_resp <- function(resp) { resp$draftables %>% diff --git a/R/competition.R b/R/competition.R index f26428f..c68786a 100644 --- a/R/competition.R +++ b/R/competition.R @@ -6,7 +6,7 @@ #' team IDs, and sport name. #' #' @inheritParams dk_get_contest_info -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @param draft_group_id Sequence of digits that correspond to a draft table/group. #' @@ -30,7 +30,7 @@ dk_get_competitions <- function(draft_group_id = NULL, output <- rlang::arg_match(output) - req <- dk_request( + req <- dk_req( ..., paths = glue::glue( "sports/v1/competitions?draftGroupId={draft_group_id}&format=json" @@ -40,6 +40,6 @@ dk_get_competitions <- function(draft_group_id = NULL, process_args <- c(list(req = req, output = output, objclass = "competitions_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } diff --git a/R/contest.R b/R/contest.R index 0df431a..74bf96e 100644 --- a/R/contest.R +++ b/R/contest.R @@ -3,14 +3,14 @@ #' #' Fetch contest information such as the sport, payout, and contest summary. #' -#' @inheritParams dk_request_process -#' @inheritDotParams dk_request +#' @inheritParams dk_req_process +#' @inheritDotParams dk_req #' #' @param contest_key The sequence of digits that correspond to a specific contest. #' This can be found by examining the URL of a contest page. #' For example: \url{https://www.draftkings.com/draft/contest/133645678#}. Here the contest ID #' is 133645678. -#' @param process_args Optional list of arguments passed to `dk_request_process` +#' @param process_args Optional list of arguments passed to `dk_req_process` #' #' @examples #' \dontrun{ @@ -26,7 +26,7 @@ dk_get_contest_info <- function(contest_key, stopifnot(is.numeric(contest_key)) output <- rlang::arg_match(output) - req <- dk_request( + req <- dk_req( ..., paths = glue::glue("contests/v1/contests/{contest_key}"), query_params = list(format = "json") @@ -34,7 +34,7 @@ dk_get_contest_info <- function(contest_key, process_args <- c(list(req = req, output = output, objclass = "contest_info_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } @@ -42,9 +42,9 @@ dk_get_contest_info <- function(contest_key, #' #' Fetch the full table of contests and related info from DraftKings.com lobby #' -#' @inheritParams dk_request_process +#' @inheritParams dk_req_process #' @inheritParams dk_get_contest_info -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @param sport character. optional. #' @@ -56,7 +56,7 @@ dk_get_lobby_contests <- function(sport = NULL, output <- rlang::arg_match(output) - req <- dk_request( + req <- dk_req( ..., base_url = "https://www.draftkings.com/", paths = "lobby/getcontests", @@ -66,7 +66,7 @@ dk_get_lobby_contests <- function(sport = NULL, process_args <- c(list(req = req, output = output, objclass = "lobby_contests_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } @@ -74,9 +74,9 @@ dk_get_lobby_contests <- function(sport = NULL, #' #' Fetch rules corresponding to a specific game type ID. #' -#' @inheritParams dk_request_process +#' @inheritParams dk_req_process #' @inheritParams dk_get_contest_info -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @param game_type_id Integer corresponding to the game type. #' For example, 159 in \url{https://api.draftkings.com/lineups/v1/gametypes/159/rules}. @@ -105,7 +105,7 @@ dk_get_game_type_rules <- function(game_type_id = NULL, } - req <- dk_request( + req <- dk_req( ..., paths = glue::glue("lineups/v1/gametypes/{game_type_id}/rules") ) @@ -113,7 +113,7 @@ dk_get_game_type_rules <- function(game_type_id = NULL, process_args <- c(list(req = req, output = output, objclass = "game_type_rules_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } @@ -122,7 +122,7 @@ dk_get_game_type_rules <- function(game_type_id = NULL, #' Fetch the full list of game types #' #' @inheritParams dk_get_lobby_contests -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @export dk_get_lobby_game_types <- function(sport = NULL, @@ -132,7 +132,7 @@ dk_get_lobby_game_types <- function(sport = NULL, output <- rlang::arg_match(output) - req <- dk_request( + req <- dk_req( ..., base_url = "https://www.draftkings.com/", paths = "lobby/getcontests", @@ -143,6 +143,6 @@ dk_get_lobby_game_types <- function(sport = NULL, process_args <- c(list(req = req, output = output, objclass = "lobby_game_types_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } diff --git a/R/draftgroup.R b/R/draftgroup.R index abb1de6..e2e4ca9 100644 --- a/R/draftgroup.R +++ b/R/draftgroup.R @@ -33,7 +33,7 @@ check_draft_group_id <- function(draft_group_id = NULL, contest_key = NULL) { #' their salaries. #' #' @inheritParams dk_get_contest_info -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @param draft_group_id Sequence of digits that correspond to a draft table/group. #' If `draft_group_id` and `contest_key` are both passed, `contest_key` is ignored. @@ -61,7 +61,7 @@ dk_get_draft_group <- function(draft_group_id = NULL, draft_group_id <- check_draft_group_id(draft_group_id, contest_key) - req <- dk_request( + req <- dk_req( ..., paths = glue::glue( "/draftgroups/v1/draftgroups/{draft_group_id}/draftables/", @@ -72,7 +72,7 @@ dk_get_draft_group <- function(draft_group_id = NULL, process_args <- c(list(req = req, output = output, objclass = "draft_group_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } @@ -82,7 +82,7 @@ dk_get_draft_group <- function(draft_group_id = NULL, #' currently present at \url{www.draftkings.com/lobby}. #' #' @inheritParams dk_get_lobby_contests -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @export dk_get_lobby_draft_groups <- function(sport = NULL, @@ -92,7 +92,7 @@ dk_get_lobby_draft_groups <- function(sport = NULL, output <- rlang::arg_match(output) - req <- dk_request( + req <- dk_req( ..., base_url = "https://www.draftkings.com/", paths = "lobby/getcontests", @@ -102,7 +102,7 @@ dk_get_lobby_draft_groups <- function(sport = NULL, process_args <- c(list(req = req, output = output, objclass = "lobby_draft_groups_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } @@ -112,7 +112,7 @@ dk_get_lobby_draft_groups <- function(sport = NULL, #' Fetch info for a specific draft group #' #' @inheritParams dk_get_draft_group -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @examples #' \dontrun{ @@ -131,7 +131,7 @@ dk_get_draft_group_info <- function(draft_group_id = NULL, draft_group_id <- check_draft_group_id(draft_group_id, contest_key) - req <- dk_request( + req <- dk_req( ..., paths = glue::glue("draftgroups/v1/{draft_group_id}") ) @@ -139,7 +139,7 @@ dk_get_draft_group_info <- function(draft_group_id = NULL, process_args <- c(list(req = req, output = output, objclass = "draft_group_info_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } @@ -148,7 +148,7 @@ dk_get_draft_group_info <- function(draft_group_id = NULL, #' Fetch additional info for a specific draft group #' #' @inheritParams dk_get_draft_group -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' @param draft_group_ids One or more draft group IDs. See [dk_get_draft_group()]. #' #' @examples @@ -166,7 +166,7 @@ dk_get_draft_group_info2 <- function(draft_group_ids = NULL, output <- rlang::arg_match(output) draft_group_ids <- glue::glue_collapse(draft_group_ids, sep = ",") - req <- dk_request( + req <- dk_req( ..., paths = glue::glue("sites/US-DK/draftgroups/v3/draftgroups/{draft_group_ids}?format=json") ) @@ -174,7 +174,7 @@ dk_get_draft_group_info2 <- function(draft_group_ids = NULL, process_args <- c(list(req = req, output = output, objclass = "draft_group_info2_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } @@ -183,7 +183,7 @@ dk_get_draft_group_info2 <- function(draft_group_ids = NULL, #' Fetch list of players and related info for a specific draft group. #' #' @inheritParams dk_get_draft_group_info -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @examples #' \dontrun{ @@ -202,7 +202,7 @@ dk_get_player_list <- function(draft_group_id = NULL, draft_group_id <- check_draft_group_id(draft_group_id, contest_key) - req <- dk_request( + req <- dk_req( ..., paths = "lineup/getavailableplayers", base_url = "https://www.draftkings.com/", @@ -212,7 +212,7 @@ dk_get_player_list <- function(draft_group_id = NULL, process_args <- c(list(req = req, output = output, objclass = "player_list_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } @@ -221,7 +221,7 @@ dk_get_player_list <- function(draft_group_id = NULL, #' Fetch list of teams for a specific draft group. #' #' @inheritParams dk_get_draft_group_info -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @export dk_get_team_list <- function(draft_group_id = NULL, @@ -234,7 +234,7 @@ dk_get_team_list <- function(draft_group_id = NULL, draft_group_id <- check_draft_group_id(draft_group_id, contest_key) - req <- dk_request( + req <- dk_req( ..., paths = "lineup/getavailableplayers", base_url = "https://www.draftkings.com/", @@ -244,7 +244,7 @@ dk_get_team_list <- function(draft_group_id = NULL, process_args <- c(list(req = req, output = output, objclass = "team_list_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } @@ -254,7 +254,7 @@ dk_get_team_list <- function(draft_group_id = NULL, #' game for a given season and week (NFL) or date (NBA/MLB). #' #' @inheritParams dk_get_contest_info -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @param timeframe integer. Either the week number for NFL, or a date of the form `20230312` for #' MLB and NBA. If the timeframe format detected does not match the sport argument passed, an @@ -297,7 +297,7 @@ dk_get_player_fp <- function(timeframe, } - req <- dk_request( + req <- dk_req( ..., base_url = "https://live.draftkings.com/api/v2/", paths = path, @@ -313,6 +313,6 @@ dk_get_player_fp <- function(timeframe, process_args <- c(list(req = req, output = output, objclass = "player_fp_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } diff --git a/R/httr2-wrappers.R b/R/httr2-wrappers.R index 80e08aa..fdf41d9 100644 --- a/R/httr2-wrappers.R +++ b/R/httr2-wrappers.R @@ -5,6 +5,7 @@ #' @inheritParams httr2::req_proxy #' @param proxy_args List of arguments to [httr2::req_proxy] #' +#' @keywords internal add_proxy <- function(req, proxy_args) { if (!is.null(proxy_args)) { @@ -24,6 +25,7 @@ add_proxy <- function(req, proxy_args) { #' @inheritParams httr2::req_error #' @param curl_options List of arguments to [httr2::req_options] #' +#' @keywords internal add_curl_options <- function(req, curl_options) { if (!is.null(curl_options)) { @@ -43,6 +45,7 @@ add_curl_options <- function(req, curl_options) { #' @inheritParams httr2::req_throttle #' @param throttle_rate List of arguments to [httr2::req_throttle] #' +#' @keywords internal add_throttle <- function(req, throttle_rate) { if (!is.null(throttle_rate)) { @@ -62,6 +65,7 @@ add_throttle <- function(req, throttle_rate) { #' @inheritParams httr2::req_throttle #' @param headers List of arguments to [httr2::req_headers()] #' +#' @keywords internal add_headers <- function(req, headers) { if (!is.null(headers)) { @@ -81,6 +85,7 @@ add_headers <- function(req, headers) { #' @inheritParams httr2::req_retry #' @param retry_options List of arguments passed to [httr2::req_retry()] #' +#' @keywords internal add_retry <- function(req, retry_options) { if (!is.null(retry_options)) { @@ -102,6 +107,7 @@ add_retry <- function(req, retry_options) { #' @inheritParams httr2::req_error #' @param error_handling_options List of arguments to [httr2::req_error()] #' +#' @keywords internal add_error_handling <- function(req, error_handling_options = NULL) { if (is.null(error_handling_options)) { @@ -121,6 +127,7 @@ add_error_handling <- function(req, error_handling_options = NULL) { #' @inheritParams httr2::req_error #' @param paths List of arguments to [httr2::req_url_path_append()] #' +#' @keywords internal add_to_path <- function(req, paths) { if (!is.null(paths)) { diff --git a/R/leaderboard.R b/R/leaderboard.R index 0152c9a..8add681 100644 --- a/R/leaderboard.R +++ b/R/leaderboard.R @@ -6,9 +6,9 @@ #' fantasy points for each entry, associated user #' for each entry, rank, and winnings. #' -#' @inheritParams dk_request_process +#' @inheritParams dk_req_process #' @inheritParams dk_get_contest_info -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' @param cookie_file Path to JSON of cookies needed to perform API request. #' #' @examples @@ -44,7 +44,7 @@ dk_get_leaderboard <- function(contest_key, } req <- do.call( - dk_request, + dk_req, c( list( paths = glue::glue("scores/v1/leaderboards/{contest_key}"), @@ -60,7 +60,7 @@ dk_get_leaderboard <- function(contest_key, process_args <- c(list(req = req, output = output, objclass = "leaderboard_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } @@ -71,10 +71,10 @@ dk_get_leaderboard <- function(contest_key, #' entry, stats for each player in an entry roster, #' and the fantasy points associated to each stat. #' -#' @inheritParams dk_request_process +#' @inheritParams dk_req_process #' @inheritParams dk_get_leaderboard #' @inheritParams dk_get_draft_group -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' @param entry_keys Vector of numeric (or character) keys that correspond to a specific entry in #' a specific contest. See output from [dk_get_leaderboard()]. #' @@ -112,7 +112,7 @@ dk_get_entries <- function(draft_group_id, } req <- do.call( - dk_request, + dk_req, c( list( paths = glue::glue("scores/v2/entries/{draft_group_id}/{paste0(entry_keys, collapse = ',')}"), @@ -128,6 +128,6 @@ dk_get_entries <- function(draft_group_id, process_args <- c(list(req = req, output = output, objclass = "entries_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } diff --git a/R/req.R b/R/req.R index 9818e6d..2267b96 100644 --- a/R/req.R +++ b/R/req.R @@ -15,7 +15,7 @@ #' @param query_params A list of query parameters passed to `[httr2::req_url_query]`. #' #' @export -dk_request <- function(proxy_args = NULL, +dk_req <- function(proxy_args = NULL, curl_options = NULL, throttle_rate = NULL, headers = NULL, @@ -57,7 +57,7 @@ dk_request <- function(proxy_args = NULL, #' @return See `output`. #' @export #' -dk_request_process <- function(req, +dk_req_process <- function(req, output = c("cleaned_json", "json", "response", "request"), objclass = NULL, ...) { diff --git a/R/sports.R b/R/sports.R index a53874b..59d188b 100644 --- a/R/sports.R +++ b/R/sports.R @@ -3,10 +3,10 @@ #' #' Fetch list of sport names and IDs. #' -#' @inheritParams dk_request_process +#' @inheritParams dk_req_process #' @inheritParams dk_get_contest_info #' -#' @inheritDotParams dk_request +#' @inheritDotParams dk_req #' #' @examples #' \dontrun{ @@ -20,7 +20,7 @@ dk_get_sports <- function(output = c("cleaned_json", "json", "response", "reques output <- rlang::arg_match(output) - req <- dk_request( + req <- dk_req( ..., paths = glue::glue("sites/US-DK/sports/v1/sports"), query_params = list(format = "json") @@ -29,6 +29,6 @@ dk_get_sports <- function(output = c("cleaned_json", "json", "response", "reques process_args <- c(list(req = req, output = output, objclass = "sports_resp"), process_args) - do.call(dk_request_process, process_args) + do.call(dk_req_process, process_args) } diff --git a/R/utils.R b/R/utils.R index a05b2a3..819d3a0 100644 --- a/R/utils.R +++ b/R/utils.R @@ -5,8 +5,8 @@ #' @param unique Should the variable names be unique? #' @param minus_to_underscore By default `-` is replaced with `minus`. #' This argument replaces the hyphen with `_` (underscore) instead. -#' -#' @export +#' +#' @keywords internal clean_names <- function(.data, unique = FALSE, minus_to_underscore = FALSE) { @@ -138,8 +138,9 @@ check_df <- function(df, class_list) { #' #' Ensure the solver name passed to `dk_optimize_lineup` is available #' -#' @inheritParams ompr.roi::with_ROI +#' @param solver A string of the solver name. #' +#' @keywords internal check_solver <- function(solver) { if (!requireNamespace(glue::glue("ROI.plugin.{solver}"), quietly = TRUE)) { From 91175d8b245787fac5a6a6ccd57c2fc545a99a29 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 11:59:12 -0500 Subject: [PATCH 05/14] Update docs --- NAMESPACE | 8 +-- man/add_curl_options.Rd | 1 + man/add_error_handling.Rd | 1 + man/add_headers.Rd | 1 + man/add_proxy.Rd | 1 + man/add_retry.Rd | 1 + man/add_throttle.Rd | 1 + man/add_to_path.Rd | 1 + man/check_solver.Rd | 3 +- man/chunk.Rd | 36 ---------- man/clean_names.Rd | 1 + man/dk_get.Rd | 66 ------------------ man/dk_get_competitions.Rd | 4 +- man/dk_get_contest_info.Rd | 4 +- man/dk_get_draft_group.Rd | 4 +- man/dk_get_draft_group_info.Rd | 4 +- man/dk_get_draft_group_info2.Rd | 4 +- man/dk_get_entries.Rd | 4 +- man/dk_get_game_type_rules.Rd | 4 +- man/dk_get_leaderboard.Rd | 4 +- man/dk_get_lobby_contests.Rd | 4 +- man/dk_get_lobby_draft_groups.Rd | 4 +- man/dk_get_lobby_game_types.Rd | 4 +- man/dk_get_player_fp.Rd | 4 +- man/dk_get_player_list.Rd | 4 +- man/dk_get_sports.Rd | 4 +- man/dk_get_team_list.Rd | 4 +- man/dk_multi_get.Rd | 46 ------------ man/{dk_request.Rd => dk_req.Rd} | 6 +- ...k_request_process.Rd => dk_req_process.Rd} | 6 +- man/draft.kings-package.Rd | 8 +++ man/figures/sticker.png | Bin 60655 -> 39230 bytes man/multi_req_perform2.Rd | 61 ---------------- 33 files changed, 57 insertions(+), 251 deletions(-) delete mode 100644 man/chunk.Rd delete mode 100644 man/dk_get.Rd delete mode 100644 man/dk_multi_get.Rd rename man/{dk_request.Rd => dk_req.Rd} (96%) rename man/{dk_request_process.Rd => dk_req_process.Rd} (92%) delete mode 100644 man/multi_req_perform2.Rd diff --git a/NAMESPACE b/NAMESPACE index f8e460e..dd40d83 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,6 +7,7 @@ S3method(dk_resp_parse,contest_info_resp) S3method(dk_resp_parse,default) S3method(dk_resp_parse,draft_group_info2_resp) S3method(dk_resp_parse,draft_group_info_resp) +S3method(dk_resp_parse,draft_group_resp) S3method(dk_resp_parse,entries_resp) S3method(dk_resp_parse,game_type_rules_resp) S3method(dk_resp_parse,leaderboard_resp) @@ -23,9 +24,7 @@ S3method(print,classic_solution) S3method(print,showdown_captain_mode_multiple_solutions) S3method(print,showdown_captain_mode_solution) export("%>%") -export(clean_names) export(dk_extract_solution) -export(dk_get) export(dk_get_competitions) export(dk_get_contest_info) export(dk_get_draft_group) @@ -42,12 +41,11 @@ export(dk_get_player_fp) export(dk_get_player_list) export(dk_get_sports) export(dk_get_team_list) -export(dk_multi_get) export(dk_optimize_lineup) export(dk_prepare_schematic) +export(dk_req) export(dk_req_perform) -export(dk_request) -export(dk_request_process) +export(dk_req_process) export(dk_resp_parse) export(dk_write_csv) importFrom(magrittr,"%>%") diff --git a/man/add_curl_options.Rd b/man/add_curl_options.Rd index 4930bc5..9a6d130 100644 --- a/man/add_curl_options.Rd +++ b/man/add_curl_options.Rd @@ -14,3 +14,4 @@ add_curl_options(req, curl_options) \description{ Add list of curl arguments to a request object } +\keyword{internal} diff --git a/man/add_error_handling.Rd b/man/add_error_handling.Rd index c8cfbfa..771041d 100644 --- a/man/add_error_handling.Rd +++ b/man/add_error_handling.Rd @@ -15,3 +15,4 @@ add_error_handling(req, error_handling_options = NULL) Add list of arguments to a request object that when errors occur and how the message is extracted. } +\keyword{internal} diff --git a/man/add_headers.Rd b/man/add_headers.Rd index 7beec2e..1e92a70 100644 --- a/man/add_headers.Rd +++ b/man/add_headers.Rd @@ -14,3 +14,4 @@ add_headers(req, headers) \description{ Add list of arguments for \code{httr2::req_headers} to a request object } +\keyword{internal} diff --git a/man/add_proxy.Rd b/man/add_proxy.Rd index 971f551..75d633f 100644 --- a/man/add_proxy.Rd +++ b/man/add_proxy.Rd @@ -14,3 +14,4 @@ add_proxy(req, proxy_args) \description{ Add list of proxy arguments to a request object } +\keyword{internal} diff --git a/man/add_retry.Rd b/man/add_retry.Rd index 4884c52..d3dfb0a 100644 --- a/man/add_retry.Rd +++ b/man/add_retry.Rd @@ -14,3 +14,4 @@ add_retry(req, retry_options) \description{ Add list of arguments to a request object that control when a request is retried } +\keyword{internal} diff --git a/man/add_throttle.Rd b/man/add_throttle.Rd index c006900..1f61c27 100644 --- a/man/add_throttle.Rd +++ b/man/add_throttle.Rd @@ -14,3 +14,4 @@ add_throttle(req, throttle_rate) \description{ Add list of throttle arguments to a request object } +\keyword{internal} diff --git a/man/add_to_path.Rd b/man/add_to_path.Rd index 65954d5..28aab34 100644 --- a/man/add_to_path.Rd +++ b/man/add_to_path.Rd @@ -14,3 +14,4 @@ add_to_path(req, paths) \description{ Add To URL Path } +\keyword{internal} diff --git a/man/check_solver.Rd b/man/check_solver.Rd index 8fbdcad..bf8f525 100644 --- a/man/check_solver.Rd +++ b/man/check_solver.Rd @@ -7,8 +7,9 @@ check_solver(solver) } \arguments{ -\item{solver}{the 'ROI' solver name (character vector of length 1)} +\item{solver}{A string of the solver name.} } \description{ Ensure the solver name passed to \code{dk_optimize_lineup} is available } +\keyword{internal} diff --git a/man/chunk.Rd b/man/chunk.Rd deleted file mode 100644 index dc4ef78..0000000 --- a/man/chunk.Rd +++ /dev/null @@ -1,36 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dk_multi_get.R -\name{chunk} -\alias{chunk} -\title{Chunk a vector into a specified number of chunks or a specified chunk size} -\usage{ -chunk(x, n_chunks = NULL, chunk_size = NULL) -} -\arguments{ -\item{x}{A vector or other R object that can be split.} - -\item{n_chunks}{An optional integer indicating the desired number of chunks.} - -\item{chunk_size}{An optional integer indicating the desired number of elements per chunk.} -} -\value{ -A list of chunks. -} -\description{ -Chunk a vector into a specified number of chunks or a specified chunk size -} -\details{ -This function splits the input \code{x} into multiple chunks based on the specified -\code{n_chunks} or \code{chunk_size}. If both are provided, \code{chunk_size} takes precedence -and \code{n_chunks} is ignored with a warning. If neither is provided, the function -will stop with an error. The function returns a list of chunks. -} -\examples{ -\dontrun{ -vec <- 1:10 -chunk(vec, chunk_size = 3) -chunk(vec, n_chunks = 3) -} - -} -\keyword{internal} diff --git a/man/clean_names.Rd b/man/clean_names.Rd index f15cf46..e42652e 100644 --- a/man/clean_names.Rd +++ b/man/clean_names.Rd @@ -20,3 +20,4 @@ Returns vector if vector or data.frame if data.frame. \description{ Clean table or vector of names } +\keyword{internal} diff --git a/man/dk_get.Rd b/man/dk_get.Rd deleted file mode 100644 index e6f2343..0000000 --- a/man/dk_get.Rd +++ /dev/null @@ -1,66 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dk_get.R -\name{dk_get} -\alias{dk_get} -\title{Get Draft Kings Data} -\usage{ -dk_get( - func, - keys, - output = c("all", "cleaned_json", "json", "response", "request"), - retry_options = NULL, - proxy_args = NULL, - report_time = TRUE, - .progress = TRUE, - furrr_options = NULL, - ... -) -} -\arguments{ -\item{func}{A function from the \code{draft.kings} package.} - -\item{keys}{This is passed as the first argument to \code{func}.} - -\item{output}{One of "cleaned_json" (the default), -"json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used -to parse the JSON body,} - -\item{retry_options}{List of arguments passed to \code{httr2::req_retry()}. -If \code{NULL} (the default), \code{max_tries} is set to 5 and these status codes are considered -transient: 429, 500, 503, 408, 400.} - -\item{proxy_args}{List of arguments to \code{httr2::req_proxy}. -If \code{NULL} (the default), this argument will look for environmental variables -related to PacketStream. See details section for which environmental variables should -be set.} - -\item{report_time}{Should the time it took the function to complete be reported?} - -\item{.progress}{A single logical. Should a progress bar be displayed? -Only works with multisession, multicore, and multiprocess futures. Note -that if a multicore/multisession future falls back to sequential, then -a progress bar will not be displayed. - -\strong{Warning:} The \code{.progress} argument will be deprecated and removed -in a future version of furrr in favor of using the more robust -\href{https://CRAN.R-project.org/package=progressr}{progressr} -package.} - -\item{furrr_options}{Options passed to \code{furrr::furrr_options}. -If \code{NULL} (the default), then will use \code{seed} and \code{stdout} to \code{TRUE}, and ensure -required packages are passed to the workers.} - -\item{...}{Other arguments passed to underlying \code{draft.kings} function (\code{func})} -} -\description{ -Fetch DraftKings data -in parallel using Packet Stream proxies by default. -} -\details{ -If \code{proxy_args} is \code{TRUE}, then the following environmental variables should be set: - -PACKET_STREAM_URL -PACKET_STREAM_PORT -PACKET_STREAM_USER -PACKET_STREAM_PASS -} diff --git a/man/dk_get_competitions.Rd b/man/dk_get_competitions.Rd index 14bee45..7f78471 100644 --- a/man/dk_get_competitions.Rd +++ b/man/dk_get_competitions.Rd @@ -18,10 +18,10 @@ dk_get_competitions( "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_contest_info.Rd b/man/dk_get_contest_info.Rd index c43e79a..a0bb5f5 100644 --- a/man/dk_get_contest_info.Rd +++ b/man/dk_get_contest_info.Rd @@ -21,10 +21,10 @@ is 133645678.} "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_draft_group.Rd b/man/dk_get_draft_group.Rd index c69acb7..c96dec4 100644 --- a/man/dk_get_draft_group.Rd +++ b/man/dk_get_draft_group.Rd @@ -29,10 +29,10 @@ then all draftable IDs will be included in the result.} "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_draft_group_info.Rd b/man/dk_get_draft_group_info.Rd index 2fcc3cc..b41c2b1 100644 --- a/man/dk_get_draft_group_info.Rd +++ b/man/dk_get_draft_group_info.Rd @@ -25,10 +25,10 @@ is 133645678.} "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_draft_group_info2.Rd b/man/dk_get_draft_group_info2.Rd index 9d160b2..c53ca0a 100644 --- a/man/dk_get_draft_group_info2.Rd +++ b/man/dk_get_draft_group_info2.Rd @@ -18,10 +18,10 @@ dk_get_draft_group_info2( "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_entries.Rd b/man/dk_get_entries.Rd index 67409a5..76dca39 100644 --- a/man/dk_get_entries.Rd +++ b/man/dk_get_entries.Rd @@ -26,10 +26,10 @@ a specific contest. See output from \code{\link[=dk_get_leaderboard]{dk_get_lead "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_game_type_rules.Rd b/man/dk_get_game_type_rules.Rd index 48e3bfe..aa3095a 100644 --- a/man/dk_get_game_type_rules.Rd +++ b/man/dk_get_game_type_rules.Rd @@ -26,10 +26,10 @@ is 133645678.} "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_leaderboard.Rd b/man/dk_get_leaderboard.Rd index d4f1a0c..65e6c01 100644 --- a/man/dk_get_leaderboard.Rd +++ b/man/dk_get_leaderboard.Rd @@ -24,10 +24,10 @@ is 133645678.} "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_lobby_contests.Rd b/man/dk_get_lobby_contests.Rd index 6c57093..c753e34 100644 --- a/man/dk_get_lobby_contests.Rd +++ b/man/dk_get_lobby_contests.Rd @@ -18,10 +18,10 @@ dk_get_lobby_contests( "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_lobby_draft_groups.Rd b/man/dk_get_lobby_draft_groups.Rd index 38f1504..65fea4f 100644 --- a/man/dk_get_lobby_draft_groups.Rd +++ b/man/dk_get_lobby_draft_groups.Rd @@ -18,10 +18,10 @@ dk_get_lobby_draft_groups( "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_lobby_game_types.Rd b/man/dk_get_lobby_game_types.Rd index 5ac7c75..c63aae7 100644 --- a/man/dk_get_lobby_game_types.Rd +++ b/man/dk_get_lobby_game_types.Rd @@ -18,10 +18,10 @@ dk_get_lobby_game_types( "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_player_fp.Rd b/man/dk_get_player_fp.Rd index b653c44..26858e3 100644 --- a/man/dk_get_player_fp.Rd +++ b/man/dk_get_player_fp.Rd @@ -26,10 +26,10 @@ error is returned.} "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_player_list.Rd b/man/dk_get_player_list.Rd index 44efbb4..332b09c 100644 --- a/man/dk_get_player_list.Rd +++ b/man/dk_get_player_list.Rd @@ -25,10 +25,10 @@ is 133645678.} "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_sports.Rd b/man/dk_get_sports.Rd index 137a908..854fb5f 100644 --- a/man/dk_get_sports.Rd +++ b/man/dk_get_sports.Rd @@ -15,10 +15,10 @@ dk_get_sports( "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_get_team_list.Rd b/man/dk_get_team_list.Rd index b939b12..44aa510 100644 --- a/man/dk_get_team_list.Rd +++ b/man/dk_get_team_list.Rd @@ -25,10 +25,10 @@ is 133645678.} "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used to parse the JSON body,} -\item{process_args}{Optional list of arguments passed to \code{dk_request_process}} +\item{process_args}{Optional list of arguments passed to \code{dk_req_process}} \item{...}{ - Arguments passed on to \code{\link[=dk_request]{dk_request}} + Arguments passed on to \code{\link[=dk_req]{dk_req}} \describe{ \item{\code{query_params}}{A list of query parameters passed to \verb{[httr2::req_url_query]}.} \item{\code{proxy_args}}{List of arguments to \link[httr2:req_proxy]{httr2::req_proxy}} diff --git a/man/dk_multi_get.Rd b/man/dk_multi_get.Rd deleted file mode 100644 index 765bb74..0000000 --- a/man/dk_multi_get.Rd +++ /dev/null @@ -1,46 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dk_multi_get.R -\name{dk_multi_get} -\alias{dk_multi_get} -\title{Get Draft Kings Data in Parallel} -\usage{ -dk_multi_get( - reqs, - paths = NULL, - chunk_size = NULL, - n_chunks = NULL, - batch_sleep = 3, - retry_sleep = 3, - report_time = TRUE, - .progress = TRUE, - ... -) -} -\arguments{ -\item{reqs}{A list of \link[httr2]{request}s.} - -\item{paths}{An optional list of paths, if you want to download the request -bodies to disks. If supplied, must be the same length as \code{reqs}.} - -\item{chunk_size, n_chunks}{Arguments passed to \code{\link[=chunk]{chunk()}}. -By default, \code{reqs} is not batched into chunks.} - -\item{batch_sleep}{Delay in seconds between batches defined by \code{chunk_size} or \code{n_chunks}.} - -\item{retry_sleep}{Delay in seconds between retries. See \code{\link[=multi_req_perform2]{multi_req_perform2()}} for details.} - -\item{report_time}{Should the time it took the function to complete be reported?} - -\item{.progress}{Whether to show a progress bar. Use \code{TRUE} to turn on -a basic progress bar, use a string to give it a name, or see -\link[purrr]{progress_bars} for more details.} - -\item{...}{Other arguments passed to \code{\link[=multi_req_perform2]{multi_req_perform2()}}.} -} -\value{ -A list of \code{httr2} response objects returned by \code{\link[httr2:multi_req_perform]{httr2::multi_req_perform()}} -} -\description{ -Fetch DraftKings data in parallel using \code{httr2::multi_req_perform()} -with retry logic and in batches. -} diff --git a/man/dk_request.Rd b/man/dk_req.Rd similarity index 96% rename from man/dk_request.Rd rename to man/dk_req.Rd index c931feb..20bbbf3 100644 --- a/man/dk_request.Rd +++ b/man/dk_req.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/req.R -\name{dk_request} -\alias{dk_request} +\name{dk_req} +\alias{dk_req} \title{Create Draft Kings Request Object} \usage{ -dk_request( +dk_req( proxy_args = NULL, curl_options = NULL, throttle_rate = NULL, diff --git a/man/dk_request_process.Rd b/man/dk_req_process.Rd similarity index 92% rename from man/dk_request_process.Rd rename to man/dk_req_process.Rd index e56b966..a8379d9 100644 --- a/man/dk_request_process.Rd +++ b/man/dk_req_process.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/req.R -\name{dk_request_process} -\alias{dk_request_process} +\name{dk_req_process} +\alias{dk_req_process} \title{Process Draft Kings Request Object} \usage{ -dk_request_process( +dk_req_process( req, output = c("cleaned_json", "json", "response", "request"), objclass = NULL, diff --git a/man/draft.kings-package.Rd b/man/draft.kings-package.Rd index 3b8fa85..1ccc129 100644 --- a/man/draft.kings-package.Rd +++ b/man/draft.kings-package.Rd @@ -7,5 +7,13 @@ \title{draft.kings: Draft Kings API Wrapper and Optimization} \description{ Fetch data from DraftKings using the provided API and perform lineup optimization. +} +\seealso{ +Useful links: +\itemize{ + \item \url{https://gacolitti.github.io/draft.kings} + \item Report bugs at \url{https://github.com/gacolitti/draft.kings/issues} +} + } \keyword{internal} diff --git a/man/figures/sticker.png b/man/figures/sticker.png index d1fe7f682676519dc296d849da2c8980c83899cb..d31b88619da72a3bdc4fd557230207e9e4641188 100644 GIT binary patch literal 39230 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 U6WF&a5x|eMxPn-@sKM9&0O_+1DgXcg diff --git a/man/multi_req_perform2.Rd b/man/multi_req_perform2.Rd deleted file mode 100644 index 84c37fb..0000000 --- a/man/multi_req_perform2.Rd +++ /dev/null @@ -1,61 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dk_multi_get.R -\name{multi_req_perform2} -\alias{multi_req_perform2} -\title{Perform multiple requests in parallel} -\usage{ -multi_req_perform2( - reqs, - max_tries = 1, - retry_sleep = 3, - is_transient = NULL, - paths = NULL, - verbose = FALSE, - ... -) -} -\arguments{ -\item{reqs}{A list of \link[httr2]{request}s.} - -\item{max_tries}{Maximum number of retry attempts for responses that are flagged as -transient with the \code{is_transient} function. By default, will retry 1 time.} - -\item{retry_sleep}{A numeric value indicating the number of seconds to sleep -after performing the requests. If NULL or negative, no sleep is performed.} - -\item{is_transient}{A predicate function that takes a single argument (the response) and -returns TRUE or FALSE specifying whether or not the response represents a transient error. -By default, requests with a 429, 503, or 403 status code are treated as transient, -as well as requests that completely failed and returned no status code.} - -\item{paths}{An optional list of paths, if you want to download the request -bodies to disks. If supplied, must be the same length as \code{reqs}.} - -\item{verbose}{Should messages related to retry logic be reported?} - -\item{...}{Other arguments passed to \code{\link[httr2:multi_req_perform]{httr2::multi_req_perform()}}} -} -\value{ -A list of responses from \code{\link[httr2:multi_req_perform]{httr2::multi_req_perform()}}. -} -\description{ -\code{multi_req_perform2} performs multiple HTTP requests concurrently -and optionally retries failed attempts. -} -\details{ -This function is a wrapper around \code{\link[httr2:multi_req_perform]{httr2::multi_req_perform()}} that allows for -the introduction of retry logic if some requests meet user-defined criteria. -This can be useful for sending many requests that are likely to encounter transient -errors that can be resolved with additional attempts. -} -\examples{ -\dontrun{ -req_list <- list( - httr2::request("http://httpbin.org/get"), - httr2::request("http://httpbin.org/get") -) -responses <- multi_req_perform2(req_list, retry_sleep = 2) -} - -} -\keyword{internal} From 725d8bfe5182022f2ef16bf2d29d92625664d9fb Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 12:00:08 -0500 Subject: [PATCH 06/14] Add basic pkgdown site and github workflow for site --- .github/workflows/pkgdown.yml | 39 +++++++++++ .gitignore | 1 + DESCRIPTION | 3 + pkgdown/_pkgdown.yml | 27 ++++++++ pkgdown/extra.css | 120 ++++++++++++++++++++++++++++++++++ renv.lock | 46 ++++++------- 6 files changed, 214 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/pkgdown.yml create mode 100644 pkgdown/_pkgdown.yml create mode 100644 pkgdown/extra.css diff --git a/.github/workflows/pkgdown.yml b/.github/workflows/pkgdown.yml new file mode 100644 index 0000000..75646b6 --- /dev/null +++ b/.github/workflows/pkgdown.yml @@ -0,0 +1,39 @@ +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + release: + types: [published] + workflow_dispatch: + +name: pkgdown + +jobs: + pkgdown: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::pkgdown, local::. + needs: website + + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy to GitHub pages 🚀 + if: github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@4.1.4 + with: + clean: false + branch: gh-pages + folder: docs diff --git a/.gitignore b/.gitignore index 221b531..cd11f7a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .RData .Ruserdata .Renviron +docs/ \ No newline at end of file diff --git a/DESCRIPTION b/DESCRIPTION index 239e196..f47880a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -29,8 +29,11 @@ Suggests: devtools, diffviewer, httptest2, + pkgdown, ROI.plugin.glpk, testthat (>= 3.0.0), usethis Config/testthat/edition: 3 Roxygen: list(markdown = TRUE) +URL: https://gacolitti.github.io/draft.kings +BugReports: https://github.com/gacolitti/draft.kings/issues diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml new file mode 100644 index 0000000..251df54 --- /dev/null +++ b/pkgdown/_pkgdown.yml @@ -0,0 +1,27 @@ +url: https://gacolitti.github.io/draft.kings/ +template: + bootstrap: 5 + bootswatch: lumen + +navbar: + structure: + left: [intro, reference, articles, tutorials, news] + right: [search, github] + +reference: +- title: "Data Fetching" + desc: "Functions for fetching DraftKings data" + contents: + - starts_with("dk_get_") +- title: "Optimization" + desc: "Functions for lineup optimization" + contents: + - starts_with("dk_optimize") + - starts_with("dk_prepare") + - starts_with("dk_extract") + - "dk_write_csv" +- title: "API Functions" + desc: "Low-level functions for interacting with the DraftKings API" + contents: + - starts_with("dk_req") + - starts_with("dk_resp_") diff --git a/pkgdown/extra.css b/pkgdown/extra.css new file mode 100644 index 0000000..314391e --- /dev/null +++ b/pkgdown/extra.css @@ -0,0 +1,120 @@ +@import url('https://fonts.googleapis.com/css?family=Raleway|Ubuntu+Mono'); + +h1, h2, h3, h4, h5{ + color: #081642; +} + +body{ + font-family: 'Raleway', sans-serif; +} + +code{ + font-family: 'Ubuntu Mono', monospace; +} + +p>a { + color: #F72C5B; +} + +li>a { + color: #F72C5B; +} + +.sourceCode>a{ + color: #081642; +} + +.st{ + color: #F72C5B; +} + +.op{ + color: #666666; +} + +.dv, .dt{ + color: #191919; +} + +.btn-copy-ex:hover{ + background-color: #F72C5B; + border-color: #081642; +} + +.btn-copy-ex{ + background-color: #081642; + border-color: #F72C5B; +} + +pre { + box-shadow: + rgba(0, 0, 0, 0.1) 0 2px 3px 1px, + rgba(0, 0, 0, 0.1) 0 1px 3px 1px, + rgba(0, 0, 0, 0.2) 0 1px 1px -1px; +} + +.navbar-default{ + color: #081642; + border-color: #F72C5B; + background-color: #FFF; +} + +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #081642; + background-color: #F72C5B; +} + +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #081642; +} + + .navbar-default .navbar-nav .open .dropdown-menu>li>a, .navbar-default .navbar-nav .open .dropdown-menu { + border-color: #F72C5B; + background-color: #FFF; +} + +.navbar-default .navbar-nav > .dropdown > a .caret { + color: #081642; +} +.navbar-default .navbar-nav > .dropdown > a:hover .caret, +.navbar-default .navbar-nav > .dropdown > a:focus .caret { + color: #F72C5B; +} + +.navbar-default .navbar-nav>.open>a, +.navbar-default .navbar-nav>.open>a:hover, +.navbar-default .navbar-nav>.open>a:focus{ + color: #081642; +} + +.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover, +.navbar-default .navbar-nav .open .dropdown-menu{ + color: #081642; +} + +.nav-pills>li.active>a, +.nav-pills>li.active>a:hover, +.nav-pills>li.active>a:focus { + color: #FFF; + background-color: #F72C5B; +} + +#navbar > ul:nth-child(1) > li.dropdown.active.open > ul > li.active > a{ + color: #FFF; + background-color: #F72C5B; +} + +a:hover, a:focus { + color: #F72C5B; +} + +.version{ + font-size: 9px; +} + +.navbar-default{ + font-size: 13px; +} diff --git a/renv.lock b/renv.lock index c9b4c89..b4c8d28 100644 --- a/renv.lock +++ b/renv.lock @@ -1,6 +1,6 @@ { "R": { - "Version": "4.3.1", + "Version": "4.4.1", "Repositories": [ { "Name": "CRAN", @@ -95,14 +95,14 @@ }, "cli": { "Package": "cli", - "Version": "3.6.1", + "Version": "3.6.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "89e6d8219950eac806ae0c489052048a" + "Hash": "b21916dd77a27642b447374a5d30ecf3" }, "codetools": { "Package": "codetools", @@ -126,13 +126,13 @@ }, "curl": { "Package": "curl", - "Version": "5.0.2", + "Version": "5.2.2", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "511bacbfa153a15251166b463b4da4f9" + "Hash": "8f27335f2bcff4d6035edcc82d7d46de" }, "data.table": { "Package": "data.table", @@ -193,10 +193,10 @@ }, "fastmap": { "Package": "fastmap", - "Version": "1.1.1", + "Version": "1.2.0", "Source": "Repository", - "Repository": "RSPM", - "Hash": "f7736a18de97dea803bde0a2daaafb27" + "Repository": "CRAN", + "Hash": "aa5e1cd11c2d15497494c5292d7ffcc8" }, "furrr": { "Package": "furrr", @@ -253,43 +253,45 @@ }, "glue": { "Package": "glue", - "Version": "1.6.2", + "Version": "1.7.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e" + "Hash": "e0b3a53876554bd45879e596cdb10a52" }, "httr2": { "Package": "httr2", - "Version": "0.2.3", + "Version": "1.0.3", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", "cli", "curl", "glue", + "lifecycle", "magrittr", "openssl", "rappdirs", "rlang", + "vctrs", "withr" ], - "Hash": "193bb297368afbbb42dc85784a46b36e" + "Hash": "10d93e97faad6b629301bb3a2fd23378" }, "jsonlite": { "Package": "jsonlite", - "Version": "1.8.7", + "Version": "1.8.8", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "methods" ], - "Hash": "266a20443ca13c65688b2116d5220f76" + "Hash": "e1b9c55281c5adc4dd113652d9e26768" }, "lattice": { "Package": "lattice", @@ -489,14 +491,14 @@ }, "rlang": { "Package": "rlang", - "Version": "1.1.1", + "Version": "1.1.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "a85c767b55f0bf9b7ad16c6d7baee5bb" + "Hash": "3eec01f8b1dee337674b2e34ab1f9bc1" }, "slam": { "Package": "slam", From 1f5bd86af9b00a492f71ca1bccbb4eddeb1cb893 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 13:24:32 -0500 Subject: [PATCH 07/14] Remove furrr dependency --- DESCRIPTION | 4 +- renv.lock | 178 ++++++++++++++-------------------------------------- 2 files changed, 49 insertions(+), 133 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f47880a..c61f4d7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -11,7 +11,6 @@ LazyData: true Imports: cli, dplyr, - furrr, glue, httr2, jsonlite, @@ -29,7 +28,9 @@ Suggests: devtools, diffviewer, httptest2, + knitr, pkgdown, + rmarkdown, ROI.plugin.glpk, testthat (>= 3.0.0), usethis @@ -37,3 +38,4 @@ Config/testthat/edition: 3 Roxygen: list(markdown = TRUE) URL: https://gacolitti.github.io/draft.kings BugReports: https://github.com/gacolitti/draft.kings/issues +VignetteBuilder: knitr diff --git a/renv.lock b/renv.lock index b4c8d28..c2c8523 100644 --- a/renv.lock +++ b/renv.lock @@ -73,17 +73,17 @@ }, "backports": { "Package": "backports", - "Version": "1.4.1", + "Version": "1.5.0", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "c39fbec8a30d23e721980b8afb31984c" + "Hash": "e1e1b9d75c37401117b636b7ae50827a" }, "checkmate": { "Package": "checkmate", - "Version": "2.3.0", + "Version": "2.3.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -91,7 +91,7 @@ "backports", "utils" ], - "Hash": "ed4275b13c6ab74b89a31def0b6bf835" + "Hash": "0e14e01ce07e7c88fd25de6d4260d26b" }, "cli": { "Package": "cli", @@ -104,25 +104,15 @@ ], "Hash": "b21916dd77a27642b447374a5d30ecf3" }, - "codetools": { - "Package": "codetools", - "Version": "0.2-19", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R" - ], - "Hash": "c089a619a7fae175d149d89164f8c7d8" - }, "cpp11": { "Package": "cpp11", - "Version": "0.4.6", + "Version": "0.5.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "707fae4bbf73697ec8d85f9d7076c061" + "Hash": "91570bba75d0c9d3f1040c835cee8fba" }, "curl": { "Package": "curl", @@ -136,31 +126,20 @@ }, "data.table": { "Package": "data.table", - "Version": "1.14.8", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "R", - "methods" - ], - "Hash": "b4c06e554f33344e044ccd7fdca750a9" - }, - "digest": { - "Package": "digest", - "Version": "0.6.33", + "Version": "1.16.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", - "utils" + "methods" ], - "Hash": "b18a9cf3c003977b0cc49d5e76ebe48d" + "Hash": "fb24e05d4a91d8b1c7ff8e284bde834a" }, "dplyr": { "Package": "dplyr", - "Version": "1.1.3", + "Version": "1.1.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "R6", @@ -177,19 +156,19 @@ "utils", "vctrs" ], - "Hash": "e85ffbebaad5f70e1a2e2ef4302b4949" + "Hash": "fedd9d00c2944ff00a0e2696ccf048ec" }, "fansi": { "Package": "fansi", - "Version": "1.0.4", + "Version": "1.0.6", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "grDevices", "utils" ], - "Hash": "1d9e7ad3c8312a192dea7d3db0274fde" + "Hash": "962174cf2aeb5b9eea581522286a911f" }, "fastmap": { "Package": "fastmap", @@ -198,37 +177,6 @@ "Repository": "CRAN", "Hash": "aa5e1cd11c2d15497494c5292d7ffcc8" }, - "furrr": { - "Package": "furrr", - "Version": "0.3.1", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R", - "future", - "globals", - "lifecycle", - "purrr", - "rlang", - "vctrs" - ], - "Hash": "da7a4c32196cb2262a41dd5a25d486ff" - }, - "future": { - "Package": "future", - "Version": "1.33.0", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "digest", - "globals", - "listenv", - "parallel", - "parallelly", - "utils" - ], - "Hash": "8e92c7bc53e91b9bb1faf9a6ef0e8514" - }, "generics": { "Package": "generics", "Version": "0.1.3", @@ -240,17 +188,6 @@ ], "Hash": "15e9634c0fcd294799e9b2e929ed1b86" }, - "globals": { - "Package": "globals", - "Version": "0.16.2", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R", - "codetools" - ], - "Hash": "baa9585ab4ce47a9f4618e671778cc6f" - }, "glue": { "Package": "glue", "Version": "1.7.0", @@ -320,16 +257,16 @@ }, "lifecycle": { "Package": "lifecycle", - "Version": "1.0.3", + "Version": "1.0.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", "glue", "rlang" ], - "Hash": "001cecbeac1cff9301bdc3775ee46a86" + "Hash": "b8552d117e1b808b09a832f589b79035" }, "listcomp": { "Package": "listcomp", @@ -342,16 +279,6 @@ ], "Hash": "4062982514dd797c7013124da49994c8" }, - "listenv": { - "Package": "listenv", - "Version": "0.9.0", - "Source": "Repository", - "Repository": "CRAN", - "Requirements": [ - "R" - ], - "Hash": "4fbd3679ec8ee169ba28d4b1ea7d0e8f" - }, "magrittr": { "Package": "magrittr", "Version": "2.0.3", @@ -396,25 +323,13 @@ }, "openssl": { "Package": "openssl", - "Version": "2.1.0", - "Source": "Repository", - "Repository": "RSPM", - "Requirements": [ - "askpass" - ], - "Hash": "273a6bb4a9844c296a459d2176673270" - }, - "parallelly": { - "Package": "parallelly", - "Version": "1.36.0", + "Version": "2.2.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ - "parallel", - "tools", - "utils" + "askpass" ], - "Hash": "bca377e1c87ec89ebed77bba00635b2e" + "Hash": "c62edf62de70cadf40553e10c739049d" }, "pillar": { "Package": "pillar", @@ -502,33 +417,33 @@ }, "slam": { "Package": "slam", - "Version": "0.1-50", + "Version": "0.1-52", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "stats" ], - "Hash": "e25793551cbdb843154152e5ee88cbd6" + "Hash": "b794b05d64b1ea017695449c410d33a9" }, "stringi": { "Package": "stringi", - "Version": "1.7.12", + "Version": "1.8.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "stats", "tools", "utils" ], - "Hash": "ca8bd84263c77310739d2cf64d84d7c9" + "Hash": "39e1144fd75428983dc3f63aa53dfa91" }, "stringr": { "Package": "stringr", - "Version": "1.5.0", + "Version": "1.5.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -539,7 +454,7 @@ "stringi", "vctrs" ], - "Hash": "671a4d384ae9d32fc47a14e98bfa3dc8" + "Hash": "960e2ae9e09656611e0b8214ad543207" }, "sys": { "Package": "sys", @@ -587,9 +502,9 @@ }, "tidyr": { "Package": "tidyr", - "Version": "1.3.0", + "Version": "1.3.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -606,13 +521,13 @@ "utils", "vctrs" ], - "Hash": "e47debdc7ce599b070c8e78e8ac0cfcf" + "Hash": "915fb7ce036c22a6a33b5a8adb712eb1" }, "tidyselect": { "Package": "tidyselect", - "Version": "1.2.0", + "Version": "1.2.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -622,23 +537,23 @@ "vctrs", "withr" ], - "Hash": "79540e5fcd9e0435af547d885f184fd5" + "Hash": "829f27b9c4919c16b593794a6344d6c0" }, "utf8": { "Package": "utf8", - "Version": "1.2.3", + "Version": "1.2.4", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "1fe17157424bb09c48a8b3b550c753bc" + "Hash": "62b65c52671e6665f803ff02954446e9" }, "vctrs": { "Package": "vctrs", - "Version": "0.6.3", + "Version": "0.6.5", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "cli", @@ -646,20 +561,19 @@ "lifecycle", "rlang" ], - "Hash": "d0ef2856b83dc33ea6e255caf6229ee2" + "Hash": "c03fa420630029418f7e6da3667aac4a" }, "withr": { "Package": "withr", - "Version": "2.5.0", + "Version": "3.0.1", "Source": "Repository", - "Repository": "RSPM", + "Repository": "CRAN", "Requirements": [ "R", "grDevices", - "graphics", - "stats" + "graphics" ], - "Hash": "c0e49a9760983e81e55cdd9be92e7182" + "Hash": "07909200e8bbe90426fbfeb73e1e27aa" } } } From 43642f22b046a04107e45dd0cd9048a13c3c3a21 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 15:56:34 -0500 Subject: [PATCH 08/14] Rename sticker.png to logo.png --- README.Rmd | 2 +- man/figures/{sticker.png => logo.png} | Bin 2 files changed, 1 insertion(+), 1 deletion(-) rename man/figures/{sticker.png => logo.png} (100%) diff --git a/README.Rmd b/README.Rmd index f5d18f4..8189ce6 100644 --- a/README.Rmd +++ b/README.Rmd @@ -13,7 +13,7 @@ knitr::opts_chunk$set( ) ``` -# draft.kings +# draft.kings diff --git a/man/figures/sticker.png b/man/figures/logo.png similarity index 100% rename from man/figures/sticker.png rename to man/figures/logo.png From 7da554c7d778739ce2090e854bdb22865ed00593 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 15:57:18 -0500 Subject: [PATCH 09/14] Add favicons using pkgdown::build_favicons() --- pkgdown/favicon/apple-touch-icon-120x120.png | Bin 0 -> 13039 bytes pkgdown/favicon/apple-touch-icon-152x152.png | Bin 0 -> 18485 bytes pkgdown/favicon/apple-touch-icon-180x180.png | Bin 0 -> 24088 bytes pkgdown/favicon/apple-touch-icon-60x60.png | Bin 0 -> 4973 bytes pkgdown/favicon/apple-touch-icon-76x76.png | Bin 0 -> 6812 bytes pkgdown/favicon/apple-touch-icon.png | Bin 0 -> 24088 bytes pkgdown/favicon/favicon-16x16.png | Bin 0 -> 1245 bytes pkgdown/favicon/favicon-32x32.png | Bin 0 -> 2393 bytes pkgdown/favicon/favicon.ico | Bin 0 -> 15086 bytes 9 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 pkgdown/favicon/apple-touch-icon-120x120.png create mode 100644 pkgdown/favicon/apple-touch-icon-152x152.png create mode 100644 pkgdown/favicon/apple-touch-icon-180x180.png create mode 100644 pkgdown/favicon/apple-touch-icon-60x60.png create mode 100644 pkgdown/favicon/apple-touch-icon-76x76.png create mode 100644 pkgdown/favicon/apple-touch-icon.png create mode 100644 pkgdown/favicon/favicon-16x16.png create mode 100644 pkgdown/favicon/favicon-32x32.png create mode 100644 pkgdown/favicon/favicon.ico diff --git a/pkgdown/favicon/apple-touch-icon-120x120.png b/pkgdown/favicon/apple-touch-icon-120x120.png new file mode 100644 index 0000000000000000000000000000000000000000..15bbbc66f7c083418a333897fdd4540d7edf6444 GIT binary patch literal 13039 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 literal 0 HcmV?d00001 diff --git a/pkgdown/favicon/apple-touch-icon-152x152.png b/pkgdown/favicon/apple-touch-icon-152x152.png new file mode 100644 index 0000000000000000000000000000000000000000..4a529cdcf8503c733447ace394a4f27c4d80a36c GIT binary patch literal 18485 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 literal 0 HcmV?d00001 diff --git a/pkgdown/favicon/apple-touch-icon-180x180.png b/pkgdown/favicon/apple-touch-icon-180x180.png new file mode 100644 index 0000000000000000000000000000000000000000..8e0921fdbada88ab8b4147b59ff900e1c14654bb GIT binary patch literal 24088 zcmV))K#ISKP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 F{s)~wNk0Gp literal 0 HcmV?d00001 diff --git a/pkgdown/favicon/apple-touch-icon.png b/pkgdown/favicon/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8e0921fdbada88ab8b4147b59ff900e1c14654bb GIT binary patch literal 24088 zcmV))K#ISKP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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

d>MSpf-M^kT&fPg^ zIlx7!EE73*IQ`_M$uUrcHctOcpK<8tj9)guVv(*S6VE!M2?AMt{vm^fb*V@Ggc*qNCK95@N(+w8gRH1C+o8_ z+@!zQpFi_aM@L0R4|+E?e6hoi$$T(w@c-nyZ~2+i;o(;<`yt3QVYT+eKE~Mnu+U43 zi+*@~be~N6X2BCzRY{4euJ)r+qy6KpmY`41e}7mQJxp|#|LIkeFdTe=RC4vNuWRr1 z{NDa}SMzRoyh0n0*b;GJ`6eE3?Ya;ZYGYlRv9y ztF*K6%JAazp#44UFN;WVz1IdoyOS3Top`_68VA77@un=Y_DIz2+ zg0ww|M2aAh@PcdG|0T#3X9;o&{$HR9Ur~t(QVN*|5JrZAm?stI2t?ULq#!SwD9A(j z04R0S3wRI7{=h&>qSZ!z&Hyg{o?H2z1b+fW>+M1y#uSGevRwQxF^N|DxY=kkt~a_{ di{sA3Zv}I{tB{4L&l|B3fE-JU>51a0{{f)KDt`a~ literal 0 HcmV?d00001 diff --git a/pkgdown/favicon/favicon-32x32.png b/pkgdown/favicon/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..c0d65219d8fb90dc236cb3bf669653681f06c7a0 GIT binary patch literal 2393 zcmV-f38wamP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 F{{#HNiqil9 literal 0 HcmV?d00001 From 8c6e51bae1fed3f8162de7e72c960a8332b7b96d Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 20:41:38 -0500 Subject: [PATCH 10/14] Update README and pkgdown site --- .Rbuildignore | 3 + .gitignore | 5 +- README.Rmd | 123 +------ README.md | 725 +++++++------------------------------ pkgdown/_pkgdown.yml | 37 +- pkgdown/extra.css | 120 ------ vignettes/.gitignore | 2 + vignettes/contests.Rmd | 89 +++++ vignettes/draftgroups.Rmd | 217 +++++++++++ vignettes/leaderboard.Rmd | 65 ++++ vignettes/optimization.Rmd | 64 ++++ 11 files changed, 633 insertions(+), 817 deletions(-) delete mode 100644 pkgdown/extra.css create mode 100644 vignettes/.gitignore create mode 100644 vignettes/contests.Rmd create mode 100644 vignettes/draftgroups.Rmd create mode 100644 vignettes/leaderboard.Rmd create mode 100644 vignettes/optimization.Rmd diff --git a/.Rbuildignore b/.Rbuildignore index 698b6d9..e774f44 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -4,3 +4,6 @@ ^\.Rproj\.user$ ^README\.Rmd$ ^LICENSE\.md$ +^\.github$ +^docs$ +^pkgdown$ diff --git a/.gitignore b/.gitignore index cd11f7a..833820f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ .RData .Ruserdata .Renviron -docs/ \ No newline at end of file +docs/ +inst/doc + +/.quarto/ diff --git a/README.Rmd b/README.Rmd index 8189ce6..e199026 100644 --- a/README.Rmd +++ b/README.Rmd @@ -45,136 +45,43 @@ devtools::install_github("gacolitti/draft.kings") library(draft.kings) ``` -# Contests +# Examples -### List all contests in the Draft Kings lobby +## Contests ```{r} -dk_get_lobby_contests() |> dplyr::glimpse() +dk_get_contest_info(contest_key = 133645678) ``` +## Draft Groups -### Get info about a particular contest - -```{r} -dk_get_contest_info(contest_key = 133645678) |> dplyr::glimpse() -``` - -> **Note:** -> A contest key is the sequence of digits that correspond to a specific contest. This can be found by examining the URL of a contest page. For example: https://www.draftkings.com/draft/contest/133645678#. Here the contest ID is 133645678. - -# Draft Groups - -### List all the draft groups in the Draft Kings lobby - -```{r} -# You can pass in sport or leave it NULL to fetch all sports -dk_get_lobby_draft_groups(sport = NULL) |> dplyr::glimpse() -``` - -### Get draft group -```{r} -dk_get_draft_group(draft_group_id = 75284) |> dplyr::glimpse() - -# If you don't know the draft group ID, you can pass in the contest key -# and the draft group ID will be retrieved automatically for you. -# dk_get_draft_group(contest_key = 133645678) -``` - ->**Note:** -> A draft group is the list of players associated with a fantasy sports contest. - -### Get draft group info -```{r} -dk_get_draft_group_info(draft_group_id = 75284) |> dplyr::glimpse() -``` - -### Get more draft group info -```{r} -dk_get_draft_group_info2(draft_group_id = 75284) |> dplyr::glimpse() -``` - -### Get list of players for a draft group -```{r} -dk_get_player_list(draft_group_id = 75284) |> dplyr::glimpse() -``` - -### Get list of teams for a draft group ```{r} -dk_get_team_list(draft_group_id = 75284) |> dplyr::glimpse() +dk_get_draft_group_info(draft_group_id = 75284) ``` -### Get player fantasy points earned -```{r} -# Data starts on October 18th, 2022 for NBA -# `timeframe` represents the week of the season for NFL -dk_get_player_fp(sport = "nfl", season = 2023, timeframe = 10) |> dplyr::glimpse() -``` - -### Get competitions associated to a draft group - -```{r} -dk_get_competitions(draft_group_id = 75284) |> dplyr::glimpse() -``` - - -# Leaderboard - -#### Get player leaderboard information for a particular contest - -A leaderboard contains a list of entries in a contest, fantasy points for each entry, associated -users for each entry, rank, and winnings. +## Leaderboard & Entries ```{r} -dk_get_leaderboard(contest_key = 133645678) |> dplyr::glimpse() +dk_get_leaderboard(contest_key = 133645678) ``` ->**Note:** -> Some functions such as `dk_get_leaderboard()` require passing the session cookies to the -> function as a JSON file. - -### Get entries for a contest - -Fetch details for entries in a contest, including the drafted roster for each entry, stats for each -player in an entry roster, and the fantasy points associated to each stat. - ```{r} dk_get_entries(draft_group_id = 80584, entry_keys = c(3618408508, 3618897002)) ``` ->**Note:** -> An entry key is a numeric (or character) key that corresponds to a specific entry in a specific contest. See output from `dk_get_leaderboard()`. - -# Optimization - -`draft.kings` contains a set of functions to perform lineup optimization. By default, optimization -uses Draft Kings player point projections, but you can pass in your own player point projections. Only -NFL and NBA contest types are supported currently. - -### Prepare schematic - -To perform optimization you must first prepare a schematic. A schematic contains all the necessary -information to perform optimization including the contest type, set of players, rules, and expected -player points. +## Lineup Optimization ```{r} +# prepare schematic with contest rules and DraftKings player projections schematic <- dk_prepare_schematic(draft_group_id = 80584) -dplyr::glimpse(schematic) -``` -### Perform optimization +# run optimization +optimized_lineup <- dk_optimize_lineup(schematic) -Pass the schematic object to the optimization function: - -```{r} -optimal_lineup <- dk_optimize_lineup(schematic) +# extract solution +dk_extract_solution(optimized_lineup) ``` -### Extract solution - -Finally, extract the solution from the solved model object: - -```{r} -dk_extract_solution(optimal_lineup) |> dplyr::glimpse() -``` +# Further Reading +- [SeanDrum/Draft-Kings-API-Documentation](https://github.com/SeanDrum/Draft-Kings-API-Documentation) \ No newline at end of file diff --git a/README.md b/README.md index dbdf144..2b48ca0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# draft.kings +# draft.kings @@ -36,470 +36,83 @@ devtools::install_github("gacolitti/draft.kings") library(draft.kings) ``` -# Contests - -### List all contests in the Draft Kings lobby - -``` r -dk_get_lobby_contests() |> dplyr::glimpse() -#> Rows: 989 -#> Columns: 51 -#> $ uc 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … -#> $ ec 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … -#> $ maximum_entries_per_user 150, 22, 150, 4, 1, 20, 150, 150, 52, 1, 1… -#> $ frequent_player_points 25, 4444, 15, 333, 121, 3333, 15, 3, 20, 3… -#> $ s 13, 13, 2, 2, 2, 2, 9, 9, 4, 4, 13, 13, 13… -#> $ name "PGA $2.75M Fantasy Golf Millionaire [$1M … -#> $ entries 747, 9, 2328, 35, 27, 70, 3663, 5792, 1224… -#> $ maximum_entries 129411, 750, 7843, 136, 183, 667, 31372, 4… -#> $ entry_fee 25, 4444, 15, 333, 121, 3333, 15, 3, 20, 3… -#> $ total_payouts 2750000, 3000000, 100000, 41000, 20000, 20… -#> $ tickets FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, … -#> $ start_time_string "Thu 6:00AM", "Thu 6:00AM", "Thu 7:15PM", … -#> $ contest_start_time 2024-07-18 10:00:00, 2024-07-18 10:00:00,… -#> $ contest_key 162653658, 162653657, 162826869, 162826866… -#> $ tmpl 954955, 954879, 332779, 362394, 370785, 95… -#> $ pt 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, … -#> $ so -99999999, -99999998, -99999997, -99999996… -#> $ fwt FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, … -#> $ is_owner FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, … -#> $ start_time_type 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … -#> $ draft_group_id 108599, 108599, 108784, 108784, 108784, 10… -#> $ ulc 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … -#> $ contest_status 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, … -#> $ game_type "Classic", "Classic", "Classic", "Classic"… -#> $ ssd NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ dgpo 5750000.0, 5750000.0, 729874.6, 729874.6, … -#> $ cso 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, … -#> $ ir 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … -#> $ rl FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, … -#> $ rlc 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … -#> $ rll 99999, 99999, 99999, 99999, 99999, 99999, … -#> $ sa TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, … -#> $ free_with_crowns FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, … -#> $ crown_amount 13750, 2444200, 8250, 183150, 66550, 18331… -#> $ is_bonus_finalized FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, … -#> $ is_snake_draft FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, … -#> $ attr_is_guaranteed "true", "true", "true", "true", "true", "t… -#> $ attr_lobby_class "icon-millionaire", "icon-millionaire", NA… -#> $ attr_is_starred "true", "true", "true", "true", "true", "t… -#> $ pd_cash "$2,750,000", "$3,000,000", "$100,000", "$… -#> $ pd_contest_seat NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ attr_is_tournament_of_champ NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ attr_is_qualifier NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ pd_live_final_seat NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ attr_is_winner_take_all NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ attr_league NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ attr_hide_branded_logo NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ attr_is_double_up NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ attr_is_fiftyfifty NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ attr_is_headliner NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -#> $ attr_is_nighttime NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA… -``` - -### Get info about a particular contest - -``` r -dk_get_contest_info(contest_key = 133645678) |> dplyr::glimpse() -#> Rows: 1 -#> Columns: 33 -#> $ contest_summary "This 215-player contest features $5… -#> $ payout_description "$5,000" -#> $ is_cash_prize_only TRUE -#> $ scoring_style_id 1 -#> $ contest_state_detail "Completed" -#> $ includes_past_season_collectibles FALSE -#> $ sport "NFL" -#> $ is_guaranteed TRUE -#> $ is_private FALSE -#> $ is_resizable FALSE -#> $ was_resized FALSE -#> $ fpp_award 27 -#> $ sort_order -1001 -#> $ contest_start_time "2022-10-10T00:20:00.0000000Z" -#> $ game_type_id 96 -#> $ ticket_only_entry FALSE -#> $ game_set_key "9D8220F812DBABB10C5D296746983AAC" -#> $ contest_key "133645678" -#> $ name "NFL Showdown $5K Super Booster [Top… -#> $ draft_group_id 75284 -#> $ play_type_id 161969 -#> $ entries 215 -#> $ maximum_entries 215 -#> $ maximum_entries_per_user 6 -#> $ entry_fee 27 -#> $ crown_amount 14850 -#> $ total_payouts 5000 -#> $ contest_state "Completed" -#> $ payout_descriptions_cash "$5,000.00" -#> $ attributes_is_guranteed "true" -#> $ attributes_is_starred "true" -#> $ attributes_multiplier "true" -#> $ attributes_allow_pregeneration "true" -``` - -> **Note:** A contest key is the sequence of digits that correspond to a -> specific contest. This can be found by examining the URL of a contest -> page. For example: -> . Here the -> contest ID is 133645678. - -# Draft Groups - -### List all the draft groups in the Draft Kings lobby - -``` r -# You can pass in sport or leave it NULL to fetch all sports -dk_get_lobby_draft_groups(sport = NULL) |> dplyr::glimpse() -#> Rows: 50 -#> Columns: 17 -#> $ draft_group_id 105573, 108211, 108489, 108615, 108616, 1086… -#> $ contest_type_id 145, 145, 159, 158, 159, 159, 159, 158, 28, … -#> $ start_date "2024-09-06T00:20:00.0000000Z", "2024-09-06T… -#> $ start_date_est "2024-09-05T20:20:00.0000000", "2024-09-05T2… -#> $ sort_order 1, 3, 7, 8, 9, 10, 11, 24, 3, 999, 999, 999,… -#> $ draft_group_tag "Featured", "", "", "Featured", "", "", "Fea… -#> $ game_type_id 145, 145, 159, 158, 159, 159, 159, 158, 2, 1… -#> $ game_type NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, … -#> $ sport_sort_order 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 4,… -#> $ sport "NFL", "NFL", "NFL", "NFL", "NFL", "NFL", "N… -#> $ game_count 16, 16, 1, 3, 1, 1, 1, 3, 2, 1, 1, 10, 9, 12… -#> $ contest_start_time_suffix " (Tournament)", " (Week 1-4 Tournament)", "… -#> $ contest_start_time_type 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0,… -#> $ games NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, … -#> $ draft_group_series_id 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,… -#> $ game_set_key "28569DBC23E659B7E8CAD5AB34C86727", "28569DB… -#> $ allowugc FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, … -``` - -### Get draft group - -``` r -dk_get_draft_group(draft_group_id = 75284) |> dplyr::glimpse() -#> Rows: 106 -#> Columns: 24 -#> $ draftable_id 24633208, 24633209, 24633210, 24633211, 2463321… -#> $ first_name "Lamar", "Ja'Marr", "Joe", "Mark", "Joe", "Tee"… -#> $ last_name "Jackson", "Chase", "Burrow", "Andrews", "Mixon… -#> $ display_name "Lamar Jackson", "Ja'Marr Chase", "Joe Burrow",… -#> $ short_name "L. Jackson", "J. Chase", "J. Burrow", "M. Andr… -#> $ player_id 877745, 1109979, 878785, 820699, 820727, 978579… -#> $ player_dk_id 17173, 557826, 485441, 16963, 13893, 468715, 17… -#> $ position "QB", "WR", "QB", "TE", "RB", "WR", "QB", "WR",… -#> $ roster_slot_id 511, 511, 511, 511, 511, 511, 512, 512, 512, 51… -#> $ salary 18300, 16500, 15900, 14400, 13200, 12300, 12200… -#> $ status "None", "None", "None", "None", "None", "None",… -#> $ is_swappable FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE… -#> $ is_disabled FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE… -#> $ news_status "Recent", "Recent", "Recent", "Recent", "Recent… -#> $ player_image50 "https://dkn.gs/sports/images/nfl/players/50/17… -#> $ player_image160 "https://dkn.gs/sports/images/nfl/players/160/1… -#> $ alt_player_image50 "", "", "", "", "", "", "", "", "", "", "", "",… -#> $ alt_player_image160 "", "", "", "", "", "", "", "", "", "", "", "",… -#> $ team_id 366, 327, 327, 366, 327, 327, 366, 327, 327, 36… -#> $ team_abbreviation "BAL", "CIN", "CIN", "BAL", "CIN", "CIN", "BAL"… -#> $ player_game_hash "877745-5819761", "1109979-5819761", "878785-58… -#> $ competition_id 5819761, 5819761, 5819761, 5819761, 5819761, 58… -#> $ competition_name "CIN @ BAL", "CIN @ BAL", "CIN @ BAL", "CIN @ B… -#> $ competition_start_time "2022-10-10T00:20:00.0000000Z", "2022-10-10T00:… - -# If you don't know the draft group ID, you can pass in the contest key -# and the draft group ID will be retrieved automatically for you. -# dk_get_draft_group(contest_key = 133645678) -``` - -> **Note:** A draft group is the list of players associated with a -> fantasy sports contest. - -### Get draft group info - -``` r -dk_get_draft_group_info(draft_group_id = 75284) |> dplyr::glimpse() -#> List of 3 -#> $ info : tibble [1 × 12] (S3: tbl_df/tbl/data.frame) -#> ..$ draft_group_id : int 75284 -#> ..$ sport_id : int 1 -#> ..$ start_time_suffix: chr " (CIN vs BAL)" -#> ..$ start_time_type : chr "Normal" -#> ..$ min_start_time : chr "2022-10-10T00:20:00.0000000Z" -#> ..$ max_start_time : chr "2022-10-10T00:20:00.0000000Z" -#> ..$ draft_group_state: chr "Historical" -#> ..$ allow_ugc : logi TRUE -#> ..$ game_type_id : int 96 -#> ..$ contest_type_id : int 96 -#> ..$ sport : chr "NFL" -#> ..$ game_type : chr "SalaryCap" -#> $ games : tibble [1 × 16] (S3: tbl_df/tbl/data.frame) -#> ..$ game_id : int 5819761 -#> ..$ away_team_id : int 327 -#> ..$ home_team_id : int 366 -#> ..$ start_date : chr "2022-10-10T00:20:00.0000000Z" -#> ..$ location : chr "M&T Bank Stadium" -#> ..$ time_remaining_status : chr "Final" -#> ..$ sport : chr "NFL" -#> ..$ status : chr "Final" -#> ..$ description : chr "CIN @ BAL" -#> ..$ league : chr "NFL" -#> ..$ competition_status : chr "ScoresOfficial" -#> ..$ competition_status_detail : chr "" -#> ..$ sport_specific_data_time_remaining : chr "Final" -#> ..$ sport_specific_data_home_team_score: chr "19" -#> ..$ sport_specific_data_away_team_score: chr "17" -#> ..$ sport_specific_data_quarter : chr "4" -#> $ leagues: tibble [1 × 3] (S3: tbl_df/tbl/data.frame) -#> ..$ league_id : int 1 -#> ..$ league_name : chr "National Football League" -#> ..$ league_abbreviation: chr "NFL" -``` - -### Get more draft group info - -``` r -dk_get_draft_group_info2(draft_group_id = 75284) |> dplyr::glimpse() -#> List of 6 -#> $ draft_groups : tibble [1 × 21] (S3: tbl_df/tbl/data.frame) -#> ..$ draft_group_id : int 75284 -#> ..$ contest_type_id : int 96 -#> ..$ sport_id : int 1 -#> ..$ start_time_suffix : chr " (CIN vs BAL)" -#> ..$ start_time_type : chr "Normal" -#> ..$ min_start_time : chr "2022-10-10T00:20:00.0000000Z" -#> ..$ max_start_time : chr "2022-10-10T00:20:00.0000000Z" -#> ..$ draft_group_state : chr "Historical" -#> ..$ sort_order : int 39 -#> ..$ allow_ugc : logi TRUE -#> ..$ league_id : int 1 -#> ..$ league_name : chr "National Football League" -#> ..$ league_abbreviation : chr "NFL" -#> ..$ game_type_id : int 96 -#> ..$ game_set_key : chr "9D8220F812DBABB10C5D296746983AAC" -#> ..$ all_tags1 : chr "Featured" -#> ..$ competition_ids : chr "5819761" -#> ..$ scoring_style_id : int 1 -#> ..$ allow_lineup_creation : logi TRUE -#> ..$ is_late_draft_eligible: logi FALSE -#> ..$ last_draft_time_utc : chr "2022-10-10T00:20:00.0000000Z" -#> $ game_types : tibble [1 × 5] (S3: tbl_df/tbl/data.frame) -#> ..$ game_types_game_type_id: int 96 -#> ..$ game_types_name : chr "Showdown Captain Mode" -#> ..$ game_types_description : chr "Create your team from 1 game, while staying under the $50,000 salary cap" -#> ..$ game_types_tag : chr "" -#> ..$ game_types_sport_id : int 1 -#> $ game_styles : tibble [1 × 7] (S3: tbl_df/tbl/data.frame) -#> ..$ game_styles_game_style_id: int 48 -#> ..$ game_styles_name : chr "Showdown Captain Mode" -#> ..$ game_styles_description : chr "Create your team from 1 game, while staying under the $50,000 salary cap" -#> ..$ game_styles_draft_type : chr "SalaryCap" -#> ..$ game_styles_sport_id : int 1 -#> ..$ game_styles_sort_order : int 2 -#> ..$ game_styles_tag : chr "" -#> $ sports : tibble [1 × 8] (S3: tbl_df/tbl/data.frame) -#> ..$ sportId : int 1 -#> ..$ name : chr "NFL" -#> ..$ fullName : chr "Football" -#> ..$ sortOrder : int 3 -#> ..$ competitionTerm : chr "Game" -#> ..$ competitionTermPlural : chr "Games" -#> ..$ regionalDisplayName : chr "NFL" -#> ..$ regionalDisplayFullName: chr "Football" -#> $ competitions : tibble [1 × 22] (S3: tbl_df/tbl/data.frame) -#> ..$ competition_id : int 5819761 -#> ..$ sport : chr "NFL" -#> ..$ sport_id : int 1 -#> ..$ home_team_team_id : int 366 -#> ..$ home_team_team_name : chr "Ravens" -#> ..$ home_team_abbreviation : chr "BAL" -#> ..$ home_team_city : chr "Baltimore" -#> ..$ away_team_team_id : int 327 -#> ..$ away_team_team_name : chr "Bengals" -#> ..$ away_team_abbreviation : chr "CIN" -#> ..$ away_team_city : chr "Cincinnati" -#> ..$ start_time : chr "2022-10-10T00:20:00.0000000Z" -#> ..$ name : chr "CIN @ BAL" -#> ..$ venue : chr "M&T Bank Stadium" -#> ..$ weather_icon : chr "clear-night" -#> ..$ weather_is_dome : logi FALSE -#> ..$ starting_lineups_available: logi FALSE -#> ..$ depth_charts_available : logi TRUE -#> ..$ competition_state : chr "ScoresOfficial" -#> ..$ competition_state_detail : chr "" -#> ..$ competition_started_early : logi FALSE -#> ..$ min_start_time : chr "2022-10-10T00:20:00.0000000Z" -#> $ competition_attributes: tibble [5 × 3] (S3: tbl_df/tbl/data.frame) -#> ..$ competition_id: int [1:5] 5819761 5819761 5819761 5819761 5819761 -#> ..$ typeId : int [1:5] 8 9 22 27 32 -#> ..$ value : chr [1:5] "4" "Final" "5" "False" ... -``` - -### Get list of players for a draft group - -``` r -dk_get_player_list(draft_group_id = 75284) |> dplyr::glimpse() -#> Rows: 53 -#> Columns: 32 -#> $ player_id 877745, 1109979, 878785, 820699, 820727, 978… -#> $ did 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,… -#> $ pcode 31002, 33393, 32671, 31056, 30161, 32703, 32… -#> $ competition_id 5819761, 5819761, 5819761, 5819761, 5819761,… -#> $ first_name "Lamar", "Ja'Marr", "Joe", "Mark", "Joe", "T… -#> $ last_name "Jackson", "Chase", "Burrow", "Andrews", "Mi… -#> $ first_name_duplicate "Lamar", "Ja'Marr", "Joe", "Mark", "Joe", "T… -#> $ last_name_duplicate "Jackson", "Chase", "Burrow", "Andrews", "Mi… -#> $ jersey_number 8, 1, 9, 89, 28, 5, 27, 7, 83, 10, 17, 13, 6… -#> $ position "QB", "WR", "QB", "TE", "RB", "WR", "RB", "W… -#> $ competition_start_time 1.665361e+12, 1.665361e+12, 1.665361e+12, 1.… -#> $ team_id 366, 327, 327, 366, 327, 327, 366, 366, 327,… -#> $ home_team_id 366, 366, 366, 366, 366, 366, 366, 366, 366,… -#> $ away_team_id 327, 327, 327, 327, 327, 327, 327, 327, 327,… -#> $ home_team_abbreviation "BAL", "BAL", "BAL", "BAL", "BAL", "BAL", "B… -#> $ away_team_abbreviation "CIN", "CIN", "CIN", "CIN", "CIN", "CIN", "C… -#> $ position_id 1, 3, 1, 4, 2, 3, 2, 3, 3, 1, 1, 1, 1, 3, 2,… -#> $ roster_slot_id 512, 512, 512, 512, 512, 512, 512, 512, 512,… -#> $ slo NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, … -#> $ is_disabled FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FA… -#> $ salary 12200, 11000, 10600, 9600, 8800, 8200, 7000,… -#> $ points_per_game "23.1", "17.4", "16.3", "12.6", "15.9", "12.… -#> $ own_rate 20, 9, 3, 30, 13, 9, 13, 20, 9, 3, 3, 3, 3, … -#> $ is_swappable FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FA… -#> $ in_play_contest FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FA… -#> $ pp 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,… -#> $ injury_status "", "", "Q", "", "", "", "Q", "", "", "", ""… -#> $ news_code 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,… -#> $ large_image_url "https://dkn.gs/sports/images/nfl/players/0/… -#> $ alternate_large_image_url NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, … -#> $ small_image_url "https://dkn.gs/sports/images/nfl/players/50… -#> $ alternate_small_image_url NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, … -``` - -### Get list of teams for a draft group - -``` r -dk_get_team_list(draft_group_id = 75284) |> dplyr::glimpse() -#> Rows: 1 -#> Columns: 9 -#> $ home_team_abbreviation "BAL" -#> $ home_team_id 366 -#> $ away_team_abbreviation "CIN" -#> $ away_team_id 327 -#> $ competition_start_time 2022-10-09 20:20:00 -#> $ dh 0 -#> $ s 1 -#> $ game_status "Final" -#> $ game_status_code 4 +# Examples + +## Contests + +``` r +dk_get_contest_info(contest_key = 133645678) +#> # A tibble: 1 × 33 +#> contest_summary payout_description is_cash_prize_only scoring_style_id +#> +#> 1 This 215-player contes… $5,000 TRUE 1 +#> # ℹ 29 more variables: contest_state_detail , +#> # includes_past_season_collectibles , sport , is_guaranteed , +#> # is_private , is_resizable , was_resized , fpp_award , +#> # sort_order , contest_start_time , game_type_id , +#> # ticket_only_entry , game_set_key , contest_key , name , +#> # draft_group_id , play_type_id , entries , +#> # maximum_entries , maximum_entries_per_user , entry_fee , … +``` + +## Draft Groups + +``` r +dk_get_draft_group_info(draft_group_id = 75284) +#> $info +#> # A tibble: 1 × 12 +#> draft_group_id sport_id start_time_suffix start_time_type min_start_time +#> +#> 1 75284 1 " (CIN vs BAL)" Normal 2022-10-10T00:20:00… +#> # ℹ 7 more variables: max_start_time , draft_group_state , +#> # allow_ugc , game_type_id , contest_type_id , sport , +#> # game_type +#> +#> $games +#> # A tibble: 1 × 16 +#> game_id away_team_id home_team_id start_date location time_remaining_status +#> +#> 1 5819761 327 366 2022-10-10T0… M&T Ban… Final +#> # ℹ 10 more variables: sport , status , description , +#> # league , competition_status , competition_status_detail , +#> # sport_specific_data_time_remaining , +#> # sport_specific_data_home_team_score , +#> # sport_specific_data_away_team_score , +#> # sport_specific_data_quarter +#> +#> $leagues +#> # A tibble: 1 × 3 +#> league_id league_name league_abbreviation +#> +#> 1 1 National Football League NFL +``` + +## Leaderboard & Entries + +``` r +dk_get_leaderboard(contest_key = 133645678) +#> # A tibble: 215 × 21 +#> draft_group_id contest_key entry_key lineup_id user_name user_key +#> +#> 1 75284 133645678 3412356478 -1 GenoMike21 642864 +#> 2 75284 133645678 3416201807 -1 carlitosway9 1334845 +#> 3 75284 133645678 3416313295 -1 KidRaider3 5752908 +#> 4 75284 133645678 3416410911 -1 carlosking89 8636059 +#> 5 75284 133645678 3416034618 -1 sjamo35 8672865 +#> 6 75284 133645678 3416642033 -1 Jace2013 11763756 +#> 7 75284 133645678 3416680035 -1 Bucknutz00 417423 +#> 8 75284 133645678 3415573084 -1 JWolff33 13692689 +#> 9 75284 133645678 3416580244 -1 eracnrobert 2374855 +#> 10 75284 133645678 3415480406 -1 Maria2199 3405766 +#> # ℹ 205 more rows +#> # ℹ 15 more variables: user_entry_count , user_entry_index , +#> # time_remaining , time_remaining_unit , max_time_remaining , +#> # time_remaining_opponent , rank , fantasy_points , +#> # fantasy_points_opponent , user_name_opponent , +#> # number_tickets_won , tickets_value , winning_value , +#> # winnings , scoring_precision ``` -### Get player fantasy points earned - -``` r -# Data starts on October 18th, 2022 for NBA -# `timeframe` represents the week of the season for NFL -dk_get_player_fp(sport = "nfl", season = 2023, timeframe = 10) |> dplyr::glimpse() -#> Rows: 286 -#> Columns: 25 -#> $ player_id 557210, 1062020, 591816, 607864, 1127106, 9… -#> $ player_dk_id 19006, 485450, 18078, 13498, 560800, 19265,… -#> $ first_name "Keenan", "CeeDee", "Dak", "Brandin", "Amon… -#> $ last_name "Allen", "Lamb", "Prescott", "Cooks", "St. … -#> $ team_id 357, 331, 331, 331, 334, 347, 357, 363, 362… -#> $ position "WR", "WR", "QB", "WR", "WR", "TE", "QB", "… -#> $ salary 8800, 8500, 6700, 4200, 8300, 5000, 7700, 5… -#> $ fantasy_points 43.50, 42.50, 41.86, 35.30, 33.50, 33.40, 3… -#> $ value_icon "fire", "fire", "fire", "fire", "fire", "fi… -#> $ competition_id 5939220, 5939250, 5939250, 5939250, 5939220… -#> $ points 43.50, 42.50, 41.86, 35.30, 33.50, 33.40, 3… -#> $ sport "nfl", "nfl", "nfl", "nfl", "nfl", "nfl", "… -#> $ game_status "liveOrFinal", "liveOrFinal", "liveOrFinal"… -#> $ competition_start_time 2023-11-12 21:05:00, 2023-11-12 21:25:00, … -#> $ week_number 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,… -#> $ image_url "https://dkn.gs/sports/images/nfl/players/1… -#> $ team_city "Los Angeles", "Dallas", "Dallas", "Dallas"… -#> $ team_name "Chargers", "Cowboys", "Cowboys", "Cowboys"… -#> $ team_abbreviation "LAC", "DAL", "DAL", "DAL", "DET", "MIN", "… -#> $ opposing_team_city "Detroit", "New York", "New York", "New Yor… -#> $ opposing_team_name "Lions", "Giants", "Giants", "Giants", "Cha… -#> $ opposing_team_abbreviation "DET", "NYG", "NYG", "NYG", "LAC", "NO", "D… -#> $ fantasy_stats_num_games 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3… -#> $ fantasy_points_per_game 24.7000, 39.5333, 35.0933, 17.0667, 26.5000… -#> $ player_state NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,… -``` - -### Get competitions associated to a draft group - -``` r -dk_get_competitions(draft_group_id = 75284) |> dplyr::glimpse() -#> Rows: 1 -#> Columns: 27 -#> $ competition_id 5819761 -#> $ sport "NFL" -#> $ start_time "2022-10-10T00:20:00.0000000Z" -#> $ competition_state "ScoresOfficial" -#> $ competition_state_detail NA -#> $ time_remaining_status "Final" -#> $ home_team_team_id 366 -#> $ home_team_team_name "Ravens" -#> $ home_team_team_abbreviation "BAL" -#> $ home_team_team_city "Baltimore" -#> $ home_team_primary_color "#241773" -#> $ home_team_secondary_color "#000000" -#> $ home_team_tertiary_color "#9e7c0c" -#> $ home_team_team_logo_url "https://dkn.gs/sports/images/nfl/te… -#> $ home_team_dark_mode_team_logo_url "" -#> $ away_team_team_id 327 -#> $ away_team_team_name "Bengals" -#> $ away_team_team_abbreviation "CIN" -#> $ away_team_team_city "Cincinnati" -#> $ away_team_primary_color "#fb4f14" -#> $ away_team_secondary_color "#000000" -#> $ away_team_team_logo_url "https://dkn.gs/sports/images/nfl/te… -#> $ away_team_dark_mode_team_logo_url "" -#> $ time_remaining "Final" -#> $ home_team_score "19" -#> $ away_team_score "17" -#> $ quarter "4" -``` - -# Leaderboard - -#### Get player leaderboard information for a particular contest - -A leaderboard contains a list of entries in a contest, fantasy points -for each entry, associated users for each entry, rank, and winnings. - -``` r -dk_get_leaderboard(contest_key = 133645678) |> dplyr::glimpse() -#> Rows: 215 -#> Columns: 20 -#> $ draft_group_id 75284, 75284, 75284, 75284, 75284, 75284, 7528… -#> $ contest_key "133645678", "133645678", "133645678", "133645… -#> $ entry_key "3412356478", "3416201807", "3416313295", "341… -#> $ lineup_id -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1… -#> $ user_name "GenoMike21", "carlitosway9", "KidRaider3", "c… -#> $ user_key "642864", "1334845", "5752908", "8636059", "86… -#> $ user_entry_count 1, 1, 1, 1, 6, 1, 2, 2, 1, 1, 3, 3, 3, 1, 2, 1… -#> $ user_entry_index 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1… -#> $ time_remaining 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0… -#> $ time_remaining_unit "PMR", "PMR", "PMR", "PMR", "PMR", "PMR", "PMR… -#> $ max_time_remaining 360, 360, 360, 360, 360, 360, 360, 360, 360, 3… -#> $ time_remaining_opponent 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0… -#> $ rank 1, 1, 1, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 14,… -#> $ fantasy_points 101.41, 101.41, 101.41, 97.64, 96.32, 96.21, 9… -#> $ fantasy_points_opponent 101.41, 101.41, 101.41, 101.41, 101.41, 101.41… -#> $ user_name_opponent "carlitosway9", "GenoMike21", "GenoMike21", "G… -#> $ number_tickets_won 0, 0, 0, 0, 0, 0, NA, NA, NA, NA, NA, NA, NA, … -#> $ tickets_value 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0… -#> $ winning_value 1000, 1000, 1000, 1000, 1000, 0, 0, 0, 0, 0, 0… -#> $ winnings [1000, "Cash"], [1000, "Cash"], [1000, "Cash"… -``` - -> **Note:** Some functions such as `dk_get_leaderboard()` require -> passing the session cookies to the function as a JSON file. - -### Get entries for a contest - -Fetch details for entries in a contest, including the drafted roster for -each entry, stats for each player in an entry roster, and the fantasy -points associated to each stat. - ``` r dk_get_entries(draft_group_id = 80584, entry_keys = c(3618408508, 3618897002)) #> # A tibble: 76 × 29 @@ -524,129 +137,71 @@ dk_get_entries(draft_group_id = 80584, entry_keys = c(3618408508, 3618897002)) #> # percent_drafted_cp , player_deep_link , … ``` -> **Note:** An entry key is a numeric (or character) key that -> corresponds to a specific entry in a specific contest. See output from -> `dk_get_leaderboard()`. - -# Optimization - -`draft.kings` contains a set of functions to perform lineup -optimization. By default, optimization uses Draft Kings player point -projections, but you can pass in your own player point projections. Only -NFL and NBA contest types are supported currently. - -### Prepare schematic - -To perform optimization you must first prepare a schematic. A schematic -contains all the necessary information to perform optimization including -the contest type, set of players, rules, and expected player points. +## Lineup Optimization ``` r +# prepare schematic with contest rules and DraftKings player projections schematic <- dk_prepare_schematic(draft_group_id = 80584) -dplyr::glimpse(schematic) -#> List of 3 -#> $ draft_group : tibble [106 × 27] (S3: tbl_df/tbl/data.frame) -#> ..$ draftable_id : num [1:106] 26368922 26368923 26368924 26368925 26368926 ... -#> ..$ first_name : chr [1:106] "Josh" "Tyreek" "Stefon" "Tua" ... -#> ..$ last_name : chr [1:106] "Allen" "Hill" "Diggs" "Tagovailoa" ... -#> ..$ display_name : chr [1:106] "Josh Allen" "Tyreek Hill" "Stefon Diggs" "Tua Tagovailoa" ... -#> ..$ short_name : chr [1:106] "J. Allen" "T. Hill" "S. Diggs" "T. Tagovailoa" ... -#> ..$ player_id : num [1:106] 868199 823156 694041 973947 592195 ... -#> ..$ player_dk_id : num [1:106] 11370 11477 17102 468529 18260 ... -#> ..$ position : chr [1:106] "QB" "WR" "WR" "QB" ... -#> ..$ roster_slot_id : num [1:106] 511 511 511 511 511 511 511 512 511 511 ... -#> ..$ salary : num [1:106] 18600 16500 15900 15600 14100 13500 13200 12400 12000 11700 ... -#> ..$ status : chr [1:106] "None" "None" "None" "None" ... -#> ..$ is_swappable : logi [1:106] FALSE FALSE FALSE FALSE FALSE FALSE ... -#> ..$ is_disabled : logi [1:106] FALSE FALSE FALSE FALSE FALSE FALSE ... -#> ..$ news_status : chr [1:106] "Recent" "Recent" "Recent" "Recent" ... -#> ..$ player_image50 : chr [1:106] "https://dkn.gs/sports/images/nfl/players/50/11370.png" "https://dkn.gs/sports/images/nfl/players/50/11477.png" "https://dkn.gs/sports/images/nfl/players/50/17102.png" "https://dkn.gs/sports/images/nfl/players/50/468529.png" ... -#> ..$ player_image160 : chr [1:106] "https://dkn.gs/sports/images/nfl/players/160/11370.png" "https://dkn.gs/sports/images/nfl/players/160/11477.png" "https://dkn.gs/sports/images/nfl/players/160/17102.png" "https://dkn.gs/sports/images/nfl/players/160/468529.png" ... -#> ..$ alt_player_image50 : chr [1:106] "" "" "" "" ... -#> ..$ alt_player_image160 : chr [1:106] "" "" "" "" ... -#> ..$ team_id : num [1:106] 324 345 324 345 345 345 345 324 345 345 ... -#> ..$ team_abbreviation : chr [1:106] "BUF" "MIA" "BUF" "MIA" ... -#> ..$ player_game_hash : chr [1:106] "868199-5819869" "823156-5819869" "694041-5819869" "973947-5819869" ... -#> ..$ competition_id : num [1:106] 5819869 5819869 5819869 5819869 5819869 ... -#> ..$ competition_name : chr [1:106] "MIA @ BUF" "MIA @ BUF" "MIA @ BUF" "MIA @ BUF" ... -#> ..$ competition_start_time: chr [1:106] "2023-01-15T18:00:00.0000000Z" "2023-01-15T18:00:00.0000000Z" "2023-01-15T18:00:00.0000000Z" "2023-01-15T18:00:00.0000000Z" ... -#> ..$ exp_fp : num [1:106] 39 36.9 24.3 26.5 -0.3 ... -#> ..$ is_captain : logi [1:106] TRUE TRUE TRUE TRUE TRUE TRUE ... -#> ..$ row_number : int [1:106] 1 2 3 4 5 6 7 8 9 10 ... -#> $ rules : tibble [1 × 26] (S3: tbl_df/tbl/data.frame) -#> ..$ game_type_id : int 96 -#> ..$ game_type_name : chr "Showdown Captain Mode" -#> ..$ game_type_description : chr "Create your team from 1 game, while staying under the $50,000 salary cap" -#> ..$ lineup_configuration_id : int 81 -#> ..$ unique_players : logi TRUE -#> ..$ allow_late_swap : logi FALSE -#> ..$ error_status : logi NA -#> ..$ rules_url : chr "/help/rules/1/96" -#> ..$ draft_type : chr "SalaryCap" -#> ..$ allowed_competition_attributes: logi NA -#> ..$ scoring_divider : logi NA -#> ..$ use_optimal_lineups : logi FALSE -#> ..$ supports_players_tab : logi FALSE -#> ..$ show_bye_week_info : logi FALSE -#> ..$ original_draft_type : logi NA -#> ..$ is_season_long : logi FALSE -#> ..$ team_position_limits : logi NA -#> ..$ salary_cap_is_enabled : logi TRUE -#> ..$ salary_cap_min_value : int 0 -#> ..$ salary_cap_max_value : int 50000 -#> ..$ game_count_is_enabled : logi FALSE -#> ..$ game_count_min_value : logi NA -#> ..$ game_count_max_value : logi NA -#> ..$ team_count_is_enabled : logi TRUE -#> ..$ team_count_min_value : int 2 -#> ..$ team_count_max_value : logi NA -#> $ draft_group_id: num 80584 -#> - attr(*, "class")= chr [1:2] "showdown_captain_mode" "list" -``` - -### Perform optimization -Pass the schematic object to the optimization function: - -``` r -optimal_lineup <- dk_optimize_lineup(schematic) -``` - -### Extract solution - -Finally, extract the solution from the solved model object: - -``` r -dk_extract_solution(optimal_lineup) |> dplyr::glimpse() -#> List of 4 -#> $ optimal_lineup:'data.frame': 6 obs. of 26 variables: -#> ..$ draftable_id : num [1:6] 26368922 26368976 26368982 26368990 26368996 ... -#> ..$ first_name : chr [1:6] "Josh" "Tyreek" "Raheem" "James" ... -#> ..$ last_name : chr [1:6] "Allen" "Hill" "Mostert" "Cook" ... -#> ..$ display_name : chr [1:6] "Josh Allen" "Tyreek Hill" "Raheem Mostert" "James Cook" ... -#> ..$ short_name : chr [1:6] "J. Allen" "T. Hill" "R. Mostert" "J. Cook" ... -#> ..$ player_id : num [1:6] 868199 823156 606501 1131012 821895 ... -#> ..$ player_dk_id : num [1:6] 11370 11477 19614 640895 14871 ... -#> ..$ position : chr [1:6] "QB" "WR" "RB" "RB" ... -#> ..$ roster_slot_id : num [1:6] 511 512 512 512 512 512 -#> ..$ salary : num [1:6] 18600 11000 8000 5400 3800 3200 -#> ..$ status : chr [1:6] "None" "None" "None" "None" ... -#> ..$ is_swappable : logi [1:6] FALSE FALSE FALSE FALSE FALSE FALSE -#> ..$ is_disabled : logi [1:6] FALSE FALSE FALSE FALSE FALSE FALSE -#> ..$ news_status : chr [1:6] "Recent" "Recent" "Breaking" "Recent" ... -#> ..$ player_image50 : chr [1:6] "https://dkn.gs/sports/images/nfl/players/50/11370.png" "https://dkn.gs/sports/images/nfl/players/50/11477.png" "https://dkn.gs/sports/images/nfl/players/50/19614.png" "https://dkn.gs/sports/images/nfl/players/50/640895.png" ... -#> ..$ player_image160 : chr [1:6] "https://dkn.gs/sports/images/nfl/players/160/11370.png" "https://dkn.gs/sports/images/nfl/players/160/11477.png" "https://dkn.gs/sports/images/nfl/players/160/19614.png" "https://dkn.gs/sports/images/nfl/players/160/640895.png" ... -#> ..$ alt_player_image50 : chr [1:6] "" "" "" "" ... -#> ..$ alt_player_image160 : chr [1:6] "" "" "" "" ... -#> ..$ team_id : num [1:6] 324 345 345 324 345 345 -#> ..$ team_abbreviation : chr [1:6] "BUF" "MIA" "MIA" "BUF" ... -#> ..$ player_game_hash : chr [1:6] "868199-5819869" "823156-5819869" "606501-5819869" "1131012-5819869" ... -#> ..$ competition_id : num [1:6] 5819869 5819869 5819869 5819869 5819869 ... -#> ..$ competition_name : chr [1:6] "MIA @ BUF" "MIA @ BUF" "MIA @ BUF" "MIA @ BUF" ... -#> ..$ competition_start_time: chr [1:6] "2023-01-15T18:00:00.0000000Z" "2023-01-15T18:00:00.0000000Z" "2023-01-15T18:00:00.0000000Z" "2023-01-15T18:00:00.0000000Z" ... -#> ..$ exp_fp : num [1:6] 39 24.6 17.4 14.1 8.2 8.6 -#> ..$ is_captain : logi [1:6] TRUE FALSE FALSE FALSE FALSE FALSE -#> $ draft_group_id: num 80584 -#> $ salary_total : num 50000 -#> $ exp_fp_total : num 112 -``` +# run optimization +optimized_lineup <- dk_optimize_lineup(schematic) + +# extract solution +dk_extract_solution(optimized_lineup) +#> $optimal_lineup +#> draftable_id first_name last_name display_name short_name player_id +#> 1 26368922 Josh Allen Josh Allen J. Allen 868199 +#> 2 26368976 Tyreek Hill Tyreek Hill T. Hill 823156 +#> 3 26368982 Raheem Mostert Raheem Mostert R. Mostert 606501 +#> 4 26368990 James Cook James Cook J. Cook 1131012 +#> 5 26368996 Jason Sanders Jason Sanders J. Sanders 821895 +#> 6 26368997 Dolphins Dolphins Dolphins 345 +#> player_dk_id position roster_slot_id salary status is_swappable is_disabled +#> 1 11370 QB 511 18600 None FALSE FALSE +#> 2 11477 WR 512 11000 None FALSE FALSE +#> 3 19614 RB 512 8000 None FALSE FALSE +#> 4 640895 RB 512 5400 None FALSE FALSE +#> 5 14871 K 512 3800 None FALSE FALSE +#> 6 18401 DST 512 3200 None FALSE FALSE +#> news_status player_image50 +#> 1 Recent https://dkn.gs/sports/images/nfl/players/50/11370.png +#> 2 Recent https://dkn.gs/sports/images/nfl/players/50/11477.png +#> 3 Breaking https://dkn.gs/sports/images/nfl/players/50/19614.png +#> 4 Recent https://dkn.gs/sports/images/nfl/players/50/640895.png +#> 5 None https://dkn.gs/sports/images/nfl/players/50/14871.png +#> 6 https://dkn.gs/sports/images/nfl/teams/50/18401.png +#> player_image160 alt_player_image50 +#> 1 https://dkn.gs/sports/images/nfl/players/160/11370.png +#> 2 https://dkn.gs/sports/images/nfl/players/160/11477.png +#> 3 https://dkn.gs/sports/images/nfl/players/160/19614.png +#> 4 https://dkn.gs/sports/images/nfl/players/160/640895.png +#> 5 https://dkn.gs/sports/images/nfl/players/160/14871.png +#> 6 https://dkn.gs/sports/images/nfl/teams/160/18401.png +#> alt_player_image160 team_id team_abbreviation player_game_hash competition_id +#> 1 324 BUF 868199-5819869 5819869 +#> 2 345 MIA 823156-5819869 5819869 +#> 3 345 MIA 606501-5819869 5819869 +#> 4 324 BUF 1131012-5819869 5819869 +#> 5 345 MIA 821895-5819869 5819869 +#> 6 345 MIA 345-5819869 5819869 +#> competition_name competition_start_time exp_fp is_captain +#> 1 MIA @ BUF 2023-01-15T18:00:00.0000000Z 39.0 TRUE +#> 2 MIA @ BUF 2023-01-15T18:00:00.0000000Z 24.6 FALSE +#> 3 MIA @ BUF 2023-01-15T18:00:00.0000000Z 17.4 FALSE +#> 4 MIA @ BUF 2023-01-15T18:00:00.0000000Z 14.1 FALSE +#> 5 MIA @ BUF 2023-01-15T18:00:00.0000000Z 8.2 FALSE +#> 6 MIA @ BUF 2023-01-15T18:00:00.0000000Z 8.6 FALSE +#> +#> $draft_group_id +#> [1] 80584 +#> +#> $salary_total +#> [1] 50000 +#> +#> $exp_fp_total +#> [1] 111.9 +``` + +# Further Reading + +- [SeanDrum/Draft-Kings-API-Documentation](https://github.com/SeanDrum/Draft-Kings-API-Documentation) diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index 251df54..a97ab4e 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -1,12 +1,39 @@ url: https://gacolitti.github.io/draft.kings/ template: bootstrap: 5 - bootswatch: lumen + params: + bootswatch: lumen navbar: structure: - left: [intro, reference, articles, tutorials, news] - right: [search, github] + left: [home, reference, articles] + right: [news, github] + components: + home: + icon: fas fa-home + href: index.html + aria-label: Home + reference: + text: Reference + href: reference/index.html + articles: + text: Articles + menu: + - text: Contests + href: articles/contests.html + - text: Draft Groups + href: articles/draftgroups.html + - text: Leaderboard & Entries + href: articles/leaderboard.html + - text: Lineup Optimization + href: articles/optimization.html + news: + text: News + href: news/index.html + github: + icon: fab fa-github + href: https://github.com/gacolitti/draft.kings + aria-label: GitHub reference: - title: "Data Fetching" @@ -25,3 +52,7 @@ reference: contents: - starts_with("dk_req") - starts_with("dk_resp_") + +authors: + Giovanni Colitti: + href: https://github.com/gacolitti diff --git a/pkgdown/extra.css b/pkgdown/extra.css deleted file mode 100644 index 314391e..0000000 --- a/pkgdown/extra.css +++ /dev/null @@ -1,120 +0,0 @@ -@import url('https://fonts.googleapis.com/css?family=Raleway|Ubuntu+Mono'); - -h1, h2, h3, h4, h5{ - color: #081642; -} - -body{ - font-family: 'Raleway', sans-serif; -} - -code{ - font-family: 'Ubuntu Mono', monospace; -} - -p>a { - color: #F72C5B; -} - -li>a { - color: #F72C5B; -} - -.sourceCode>a{ - color: #081642; -} - -.st{ - color: #F72C5B; -} - -.op{ - color: #666666; -} - -.dv, .dt{ - color: #191919; -} - -.btn-copy-ex:hover{ - background-color: #F72C5B; - border-color: #081642; -} - -.btn-copy-ex{ - background-color: #081642; - border-color: #F72C5B; -} - -pre { - box-shadow: - rgba(0, 0, 0, 0.1) 0 2px 3px 1px, - rgba(0, 0, 0, 0.1) 0 1px 3px 1px, - rgba(0, 0, 0, 0.2) 0 1px 1px -1px; -} - -.navbar-default{ - color: #081642; - border-color: #F72C5B; - background-color: #FFF; -} - -.navbar-default .navbar-nav > .active > a, -.navbar-default .navbar-nav > .active > a:hover, -.navbar-default .navbar-nav > .active > a:focus { - color: #081642; - background-color: #F72C5B; -} - -.navbar-default .navbar-nav > li > a:hover, -.navbar-default .navbar-nav > li > a:focus { - color: #081642; -} - - .navbar-default .navbar-nav .open .dropdown-menu>li>a, .navbar-default .navbar-nav .open .dropdown-menu { - border-color: #F72C5B; - background-color: #FFF; -} - -.navbar-default .navbar-nav > .dropdown > a .caret { - color: #081642; -} -.navbar-default .navbar-nav > .dropdown > a:hover .caret, -.navbar-default .navbar-nav > .dropdown > a:focus .caret { - color: #F72C5B; -} - -.navbar-default .navbar-nav>.open>a, -.navbar-default .navbar-nav>.open>a:hover, -.navbar-default .navbar-nav>.open>a:focus{ - color: #081642; -} - -.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover, -.navbar-default .navbar-nav .open .dropdown-menu{ - color: #081642; -} - -.nav-pills>li.active>a, -.nav-pills>li.active>a:hover, -.nav-pills>li.active>a:focus { - color: #FFF; - background-color: #F72C5B; -} - -#navbar > ul:nth-child(1) > li.dropdown.active.open > ul > li.active > a{ - color: #FFF; - background-color: #F72C5B; -} - -a:hover, a:focus { - color: #F72C5B; -} - -.version{ - font-size: 9px; -} - -.navbar-default{ - font-size: 13px; -} diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..097b241 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1,2 @@ +*.html +*.R diff --git a/vignettes/contests.Rmd b/vignettes/contests.Rmd new file mode 100644 index 0000000..1e1b239 --- /dev/null +++ b/vignettes/contests.Rmd @@ -0,0 +1,89 @@ +--- +title: "Contests" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Contests} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(draft.kings) +``` + +# Understanding DraftKings Contests + +DraftKings is a popular daily fantasy sports platform that offers a wide variety of contests across multiple sports. These contests allow users to draft virtual teams of real players and compete against other users for prizes. This vignette will guide you through using the `draft.kings` package to interact with DraftKings contests programmatically. + +## Types of Contests + +DraftKings offers a wide variety of contest types, including: + +1. Guaranteed Prize Pools (GPPs): Large tournaments with fixed prize pools. +2. Cash Games: + - Head-to-Head: Contests between two players. + - 50/50s: Contests where the top half of entries win. + - Double-Ups: Similar to 50/50s, but winners double their entry fee. +3. Leagues: Smaller contests with a set number of entries. +4. Showdown: Single-game contests focusing on one specific matchup. +5. Tiers: Contests where players are grouped into tiers, and you select one from each tier. +6. Classic: Traditional salary cap-based contests across multiple games. +7. In-Game Showdown: Live contests that start after a game has begun. +8. Best Ball: Season-long contests with automated lineup optimization. +9. Step Tournaments: Multi-stage contests where winners advance to higher levels. +10. Beginner Contests: Restricted to newer players on the platform. +11. Satellites and Qualifiers: Contests that award entries into larger tournaments. + +Each contest type has its own strategy and appeal to different players. The `draft.kings` package provides tools to interact with and analyze these various contest types. + +## Key Concepts + +Before diving into the functions, it's important to understand a few key concepts: + +- **Contest Key**: A unique identifier for each contest. +- **Draft Group**: A set of players available for drafting in a particular contest or set of contests. +- **Draft Group ID**: A unique identifier for each draft group. + +The `draft.kings` package provides functions to interact with these elements, allowing you to fetch contest information, player data, and more. Let's explore some of these functions below. + + +# Contest Details + +## dk_get_lobby_contests() + +*List all contests in the Draft Kings lobby* + +The `dk_get_lobby_contests()` function retrieves information about all available contests in the DraftKings lobby. + +```{r} +contests <- dk_get_lobby_contests() +contests |> + dplyr::select(contest_key, name, game_type, entry_fee, entries, maximum_entries_per_user) |> + head(5) +``` + +> **Note:** +> A contest key is the sequence of digits that correspond to a specific contest. This can be found by examining the URL of a contest page. For example: https://www.draftkings.com/draft/contest/133645678#. Here the contest ID is 133645678. + + +## dk_get_contest_info() + +*Get detailed contest info by contest key* + +The `dk_get_contest_info()` function provides more detailed information about a specific contest compared to `dk_get_lobby_contests()`. While `dk_get_lobby_contests()` gives an overview of multiple contests, `dk_get_contest_info()` focuses on a single contest with in-depth details. + +```{r} +dk_get_contest_info(contest_key = 133645678) |> + dplyr::select(contest_summary, payout_description, sport, entry_fee, entries, maximum_entries) +``` + + + + diff --git a/vignettes/draftgroups.Rmd b/vignettes/draftgroups.Rmd new file mode 100644 index 0000000..fbfc2f9 --- /dev/null +++ b/vignettes/draftgroups.Rmd @@ -0,0 +1,217 @@ +--- +title: "Draft Groups" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Draft Groups} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(draft.kings) +``` + +# Understanding Draft Groups + +Draft groups are a fundamental concept in DraftKings' daily fantasy sports platform. They represent a collection of players available for selection in a specific contest or set of contests. Understanding draft groups is crucial for effectively participating in DraftKings contests and utilizing the `draft.kings` package. + +Key aspects of draft groups include: + +1. Player Pool: Each draft group contains a specific set of players from which contestants can build their lineups. + +2. Salary Cap: Draft groups typically have a salary cap, limiting the total "cost" of players that can be selected for a lineup. + +3. Positions: Players in a draft group are categorized by their positions, which vary depending on the sport. + +4. Contest Association: A draft group is linked to one or more contests. Multiple contests may share the same draft group. + +5. Sport and Game Type: Draft groups are sport-specific and may be further categorized by game type (e.g., classic, showdown). + +6. Start Time: Each draft group has a specific start time, usually corresponding to the start of the first game included in the contests. + +7. Player Information: Draft groups contain detailed information about each player, including their salary, team, and projected points. + +8. Roster Requirements: Each draft group has specific roster requirements, such as the number of players to be drafted and position limits. + +The `draft.kings` package provides several functions to interact with and analyze draft groups, allowing users to retrieve draft group information, player lists, and other relevant data for strategic lineup construction and contest analysis. + + +# Draft Groups in Lobby + +## dk_get_lobby_draft_groups() + +*List all the draft groups in the Draft Kings lobby* + +The `dk_get_lobby_draft_groups()` function retrieves information about all available draft groups in the DraftKings lobby. A draft group represents a set of players available for drafting in a particular contest or set of contests. This function can be used to get an overview of the current draft groups across different sports. + +```{r} +draft_groups <- dk_get_lobby_draft_groups() +draft_groups |> + dplyr::select(draft_group_id, game_type, sport, start_date, game_count) |> + head(5) +``` + +# Draft Group Info + +## dk_get_draft_group() + +*Get detailed draft group info by draft group ID* + +The `dk_get_draft_group()` function provides detailed information about a specific draft group. This includes data such as the sport, game type, start time, and various rules and settings for the draft group. You can use either the draft group ID directly or provide a contest key, and the function will automatically retrieve the corresponding draft group ID. + +```{r} +dk_get_draft_group(draft_group_id = 75284) |> + dplyr::select(draftable_id, display_name, player_id, salary, position, status, team_abbreviation, team_id, competition_id, competition_name, competition_start_time) +``` + +## dk_get_draft_group_info() + +*Get draft group info* + +The `dk_get_draft_group_info()` function provides a different set of information compared to `dk_get_draft_group()`. While `dk_get_draft_group()` focuses on player-specific data within a draft group, `dk_get_draft_group_info()` offers a higher-level overview of the draft group itself and associated game information. + +Key differences include: + +1. Structure: `dk_get_draft_group_info()` returns a list with three main components: info, games, and leagues. + +2. Draft Group Details: It provides overall draft group information such as sport_id, start_time_suffix, draft_group_state, and game_type. + +3. Game Information: Unlike `dk_get_draft_group()`, it includes detailed game data like location, time_remaining_status, and sport-specific scores. + +4. League Data: It also includes league-specific information not present in `dk_get_draft_group()`. + +This function is particularly useful when you need broader context about the draft group, its associated games, and league, rather than individual player details. + +Here's an example of how to use the function: + +```{r} +dgi <- dk_get_draft_group_info(draft_group_id = 75284) +info <- dgi$info +games <- dgi$games +leagues <- dgi$leagues + +info |> dplyr::select(sport, start_time_suffix, draft_group_state, game_type) +games |> dplyr::select(game_id, away_team_id, home_team_id, start_date, location) +leagues |> dplyr::select(league_id, league_name, league_abbreviation) +``` + + +## dk_get_draft_group_info2() + +*Get more draft group info* + +The `dk_get_draft_group_info2()` function provides more information compared to `dk_get_draft_group_info()`. Key differences include: + +1. Structure: + - `dk_get_draft_group_info()`: 3 components (info, games, leagues) + - `dk_get_draft_group_info2()`: 6 components (draft_groups, game_types, game_styles, sports, competitions, competition_attributes) + +2. Unique to `dk_get_draft_group_info()`: + - Detailed game-specific data like scores and quarter information + +3. Additional in `dk_get_draft_group_info2()`: + - More draft group details (e.g., sort_order, game_set_key) + - Separate game_types and game_styles components + - Detailed sports data + - Expanded competition information (e.g., weather, venue) + - Competition attributes + +`dk_get_draft_group_info2()` is particularly useful for: +- Analyzing contest rules and formats +- Accessing detailed sport and competition attributes +- Obtaining weather and venue information + +Example usage: + +```{r} +dgi2 <- dk_get_draft_group_info2(draft_group_id = 75284) + +dgi2 |> names() + +dgi2$draft_groups |> + dplyr::select(draft_group_id, contest_type_id, draft_group_state, min_start_time, max_start_time) + +dgi2$competitions |> + dplyr::select(competition_id, name, start_time, venue, weather_icon) + + +``` + +# Player and Team Data + +## dk_get_player_list() + +*Get list of players for a draft group* + +The `dk_get_player_list()` function retrieves a detailed list of players available for drafting in a specific draft group. This function is similar to `dk_get_draft_group()` and is useful for analyzing the player pool, understanding salary constraints, and making informed decisions when building lineups. Here's a breakdown of what this function provides: + +- Player details: Names, positions, team affiliations +- Fantasy-relevant information: Salary, projected points, recent performance +- Game-specific data: Opponent, game time, location +- Additional metadata: Player IDs, roster slot IDs, status + +This information is particularly useful for: +- Conducting pre-draft research +- Identifying value picks based on salary and projected points +- Analyzing matchups and game conditions +- Building optimized lineups within salary constraints + +Let's examine the output: + +```{r} +dk_get_player_list(draft_group_id = 75284) |> + dplyr::select(player_id, first_name, last_name, position, salary, points_per_game, own_rate, is_swappable, in_play_contest, pp, injury_status) +``` + +## dk_get_team_list() + +*Get list of teams for a draft group* + +The `dk_get_team_list()` function retrieves information about the teams participating in a specific draft group. This function is useful for understanding the team composition within a contest and can provide valuable context for player selection and matchup analysis. Here's what this function typically provides: + +- Team identifiers: Team IDs and abbreviations +- Game-specific information: Home/away status, opponent +- Team metadata: Full team names, locations + +This information is particularly useful for: +- Analyzing team matchups +- Identifying home and away teams +- Cross-referencing team data with player information + +Let's examine the output: + +```{r} +dk_get_team_list(draft_group_id = 75284) |> + dplyr::select(home_team_abbreviation, away_team_abbreviation, competition_start_time, game_status) +``` + +## dk_get_player_fp() + +*Get player fantasy points earned* + +The `dk_get_player_fp()` function retrieves fantasy points earned by players for a specific sport, season, and timeframe. Data starts on October 18th, 2022 for NBA. + + +```{r} +# `timeframe` represents the week of the season for NFL +dk_get_player_fp(sport = "nfl", season = 2023, timeframe = 10) |> + dplyr::select(player_id, first_name, last_name, team_id, position, salary, fantasy_points, competition_id, points, sport) +``` + +## dk_get_competitions() + +*Get competitions associated to a draft group* + +The `dk_get_competitions()` function retrieves detailed information about the competitions associated with a specific draft group. + +```{r} +dk_get_competitions(draft_group_id = 75284) |> + dplyr::select(competition_id, start_time, home_team_team_name, away_team_team_name, sport, competition_state) +``` diff --git a/vignettes/leaderboard.Rmd b/vignettes/leaderboard.Rmd new file mode 100644 index 0000000..f87b353 --- /dev/null +++ b/vignettes/leaderboard.Rmd @@ -0,0 +1,65 @@ +--- +title: "Leaderboard & Entries" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Leaderboard & Entries} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(draft.kings) +``` + +# Analyzing Contest Results and Rankings + +## dk_get_leaderboard() + +*Get player leaderboard information for a particular contest* + +The `dk_get_leaderboard()` function retrieves comprehensive information about the participants and their performance in a specific DraftKings contest. This includes: + +1. A list of all entries in the contest +2. Fantasy points scored by each entry +3. User information associated with each entry +4. Current rank of each entry +5. Winnings (if any) for each entry + +This data allows for in-depth analysis of contest results, participant performance, and payout distributions. It's particularly useful for understanding successful strategies, identifying top users, and gaining insights into contest dynamics. + +```{r} +dk_get_leaderboard(contest_key = 133645678) +``` + +>**Note:** +> Some functions such as `dk_get_leaderboard()` require passing the session cookies to the +> function as a JSON file. + +## dk_get_entries() + +*Get entries for a contest* + +Retrieve detailed information about specific entry rosters in a contest, including: + +1. The complete drafted roster for each entry +2. Detailed statistics for every player in an entry's roster +3. Fantasy points earned for each statistical category +4. Performance breakdowns and scoring details +5. Any late swap or substitution information +6. Entry metadata such as entry fees, potential winnings, and current ranking + +This function provides a deep dive into the composition and performance of individual contest entries, allowing for analysis of roster strategies and player contributions. + +```{r} +dk_get_entries(draft_group_id = 80584, entry_keys = c(3618408508, 3618897002)) +``` + +>**Note:** +> An entry key is a numeric (or character) key that corresponds to a specific entry in a specific contest. See output from `dk_get_leaderboard()`. \ No newline at end of file diff --git a/vignettes/optimization.Rmd b/vignettes/optimization.Rmd new file mode 100644 index 0000000..c06e75a --- /dev/null +++ b/vignettes/optimization.Rmd @@ -0,0 +1,64 @@ +--- +title: "Lineup Optimization" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Lineup Optimization} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(draft.kings) +``` + +# Understanding Lineup Optimization + +Lineup optimization is a crucial piece of daily fantasy sports (DFS) that involves selecting the best possible combination of players within given constraints to maximize potential points. This process is particularly important in DFS platforms like DraftKings, where participants must create lineups under specific rules and salary caps. + +Key aspects of lineup optimization in DFS include: + +1. Salary Cap Management: Balancing high-value players with budget-friendly options to stay within the allocated salary cap. + +2. Position Requirements: Fulfilling specific position quotas required by the contest rules (e.g., 1 QB, 2 RBs, 3 WRs for NFL contests). + +3. Player Projections: Utilizing accurate projections of player performance, which can be based on historical data, recent form, matchups, and other relevant factors. + + +The `draft.kings` package provides tools to streamline this optimization process, allowing users to leverage DraftKings' data and perform lineup optimization programmatically. By default, optimization +uses Draft Kings player point projections, but you can pass in your own player point projections. Only +NFL and NBA contest types are supported currently. + +## Prepare schematic + +To perform optimization you must first prepare a schematic. A schematic contains all the necessary +information to perform optimization including the contest type, set of players, rules, and expected +player points. + +```{r} +schematic <- dk_prepare_schematic(draft_group_id = 80584) +dplyr::glimpse(schematic) +``` + +## Perform optimization + +Pass the schematic object to the optimization function: + +```{r} +optimal_lineup <- dk_optimize_lineup(schematic) +``` + +## Extract solution + +Finally, extract the solution from the solved model object: + +```{r} +dk_extract_solution(optimal_lineup) |> dplyr::glimpse() +``` + From 07aee973344c9efcc2c17ec178f5bae739baf83a Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 20:42:39 -0500 Subject: [PATCH 11/14] Add NEWS.md --- NEWS.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 NEWS.md diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..d4f3f62 --- /dev/null +++ b/NEWS.md @@ -0,0 +1 @@ +# draft.kings (development version) From 9b402818e901a723cf6a38f532208259d50ee049 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 20:50:25 -0500 Subject: [PATCH 12/14] Update NEWS --- NEWS.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index d4f3f62..b336286 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1 +1,5 @@ -# draft.kings (development version) +# draft.kings 0.5.4 +* Added pkgdown site and udpated README +* Removed `dk_get()` and `dk_multi_get()` +* Renamed functions like `dk_request_*()` to `dk_req_*()` +* Renamed functions like `dk_response_*()` to `dk_resp_*()` From f129d8fd4ffa8833cb2b3ab0fa7755bc24404fe9 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sun, 1 Sep 2024 18:36:42 -0500 Subject: [PATCH 13/14] Replace cookies_file arg with iv and jwe args --- .github/workflows/pkgdown.yml | 2 ++ NEWS.md | 1 + R/leaderboard.R | 30 ++++++++++++------------------ man/dk_get_entries.Rd | 7 +++++-- man/dk_get_leaderboard.Rd | 7 +++++-- man/draft.kings-package.Rd | 2 ++ vignettes/leaderboard.Rmd | 3 +-- 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/.github/workflows/pkgdown.yml b/.github/workflows/pkgdown.yml index 75646b6..0aa3e23 100644 --- a/.github/workflows/pkgdown.yml +++ b/.github/workflows/pkgdown.yml @@ -14,6 +14,8 @@ jobs: runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + DK_IV: ${{ secrets.DK_IV }} + DK_JWE: ${{ secrets.DK_JWE }} steps: - uses: actions/checkout@v2 diff --git a/NEWS.md b/NEWS.md index b336286..c4fe838 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,3 +3,4 @@ * Removed `dk_get()` and `dk_multi_get()` * Renamed functions like `dk_request_*()` to `dk_req_*()` * Renamed functions like `dk_response_*()` to `dk_resp_*()` +* Replaced `cookies_file` argument with `iv` and `jwe` arguments to functions that require DraftKings session cookies \ No newline at end of file diff --git a/R/leaderboard.R b/R/leaderboard.R index 8add681..4783ab4 100644 --- a/R/leaderboard.R +++ b/R/leaderboard.R @@ -1,4 +1,3 @@ - #' Get Leaderboard #' #' Fetch leaderboard for a contest. A leaderboard @@ -9,7 +8,8 @@ #' @inheritParams dk_req_process #' @inheritParams dk_get_contest_info #' @inheritDotParams dk_req -#' @param cookie_file Path to JSON of cookies needed to perform API request. +#' @param iv Character string. The 'iv' cookie value. If not provided, it will be retrieved from the DK_IV environment variable. +#' @param jwe Character string. The 'jwe' cookie value. If not provided, it will be retrieved from the DK_JWE environment variable. #' #' @examples #' \dontrun{ @@ -18,22 +18,19 @@ #' #' @export dk_get_leaderboard <- function(contest_key, - cookie_file = path.expand("~/cookies.json"), + iv = Sys.getenv("DK_IV"), + jwe = Sys.getenv("DK_JWE"), output = c("cleaned_json", "json", "response", "request"), process_args = NULL, ...) { output <- rlang::arg_match(output) - if (!file.exists(cookie_file)) { - rlang::abort( - "`cookie_file` not found: {cookie_file}" - ) + if (nchar(iv) == 0 || nchar(jwe) == 0) { + rlang::abort("Both 'iv' and 'jwe' cookies are required. Set DK_IV and DK_JWE environment variables or pass them directly.") } - cook <- jsonlite::read_json(cookie_file) - clean_cook <- paste0(unlist(lapply(cook, function(x) {paste0(x$name, "=", x$value)})), - collapse = ";") + clean_cook <- paste0("iv=", iv, ";jwe=", jwe) # Update curl options to ensure it includes cookies dots_list <- list(...) @@ -86,22 +83,19 @@ dk_get_leaderboard <- function(contest_key, #' @export dk_get_entries <- function(draft_group_id, entry_keys, - cookie_file = path.expand("~/cookies.json"), + iv = Sys.getenv("DK_IV"), + jwe = Sys.getenv("DK_JWE"), output = c("cleaned_json", "json", "response", "request"), process_args = NULL, ...) { output <- rlang::arg_match(output) - if (!file.exists(cookie_file)) { - rlang::abort( - "`cookie_file` not found: {cookie_file}" - ) + if (nchar(iv) == 0 || nchar(jwe) == 0) { + rlang::abort("Both 'iv' and 'jwe' cookies are required. Set DK_IV and DK_JWE environment variables or pass them directly.") } - cook <- jsonlite::read_json(cookie_file) - clean_cook <- paste0(unlist(lapply(cook, function(x) {paste0(x$name, "=", x$value)})), - collapse = ";") + clean_cook <- paste0("iv=", iv, ";jwe=", jwe) # Update curl options to ensure it includes cookies dots_list <- list(...) diff --git a/man/dk_get_entries.Rd b/man/dk_get_entries.Rd index 76dca39..5123e1b 100644 --- a/man/dk_get_entries.Rd +++ b/man/dk_get_entries.Rd @@ -7,7 +7,8 @@ dk_get_entries( draft_group_id, entry_keys, - cookie_file = path.expand("~/cookies.json"), + iv = Sys.getenv("DK_IV"), + jwe = Sys.getenv("DK_JWE"), output = c("cleaned_json", "json", "response", "request"), process_args = NULL, ... @@ -20,7 +21,9 @@ If \code{draft_group_id} and \code{contest_key} are both passed, \code{contest_k \item{entry_keys}{Vector of numeric (or character) keys that correspond to a specific entry in a specific contest. See output from \code{\link[=dk_get_leaderboard]{dk_get_leaderboard()}}.} -\item{cookie_file}{Path to JSON of cookies needed to perform API request.} +\item{iv}{Character string. The 'iv' cookie value. If not provided, it will be retrieved from the DK_IV environment variable.} + +\item{jwe}{Character string. The 'jwe' cookie value. If not provided, it will be retrieved from the DK_JWE environment variable.} \item{output}{One of "cleaned_json" (the default), "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used diff --git a/man/dk_get_leaderboard.Rd b/man/dk_get_leaderboard.Rd index 65e6c01..c201710 100644 --- a/man/dk_get_leaderboard.Rd +++ b/man/dk_get_leaderboard.Rd @@ -6,7 +6,8 @@ \usage{ dk_get_leaderboard( contest_key, - cookie_file = path.expand("~/cookies.json"), + iv = Sys.getenv("DK_IV"), + jwe = Sys.getenv("DK_JWE"), output = c("cleaned_json", "json", "response", "request"), process_args = NULL, ... @@ -18,7 +19,9 @@ This can be found by examining the URL of a contest page. For example: \url{https://www.draftkings.com/draft/contest/133645678#}. Here the contest ID is 133645678.} -\item{cookie_file}{Path to JSON of cookies needed to perform API request.} +\item{iv}{Character string. The 'iv' cookie value. If not provided, it will be retrieved from the DK_IV environment variable.} + +\item{jwe}{Character string. The 'jwe' cookie value. If not provided, it will be retrieved from the DK_JWE environment variable.} \item{output}{One of "cleaned_json" (the default), "json", "response", or "request". If "cleaned_json" then \code{\link[tidyjson:spread_all]{tidyjson::spread_all()}} is used diff --git a/man/draft.kings-package.Rd b/man/draft.kings-package.Rd index 1ccc129..aef24fd 100644 --- a/man/draft.kings-package.Rd +++ b/man/draft.kings-package.Rd @@ -6,6 +6,8 @@ \alias{draft.kings-package} \title{draft.kings: Draft Kings API Wrapper and Optimization} \description{ +\if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}} + Fetch data from DraftKings using the provided API and perform lineup optimization. } \seealso{ diff --git a/vignettes/leaderboard.Rmd b/vignettes/leaderboard.Rmd index f87b353..38e1f57 100644 --- a/vignettes/leaderboard.Rmd +++ b/vignettes/leaderboard.Rmd @@ -39,8 +39,7 @@ dk_get_leaderboard(contest_key = 133645678) ``` >**Note:** -> Some functions such as `dk_get_leaderboard()` require passing the session cookies to the -> function as a JSON file. +> Some functions such as `dk_get_leaderboard()` and `dk_get_entries()` require authentication via DraftKings session cookies. These can be provided either by setting the `DK_IV` and `DK_JWE` environment variables, or by passing them directly to the functions using the `iv` and `jwe` arguments. ## dk_get_entries() From 031becab033d22bbe1cf92630e31b2cbf7e4fb59 Mon Sep 17 00:00:00 2001 From: Giovanni Colitti Date: Sat, 31 Aug 2024 20:45:47 -0500 Subject: [PATCH 14/14] Increment version number to 0.5.4 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index c61f4d7..19b966a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: draft.kings Type: Package Title: Draft Kings API Wrapper and Optimization -Version: 0.5.3.9000 +Version: 0.5.4 Author: Giovanni Colitti Maintainer: Giovanni Colitti Description: Fetch data from DraftKings using the provided API and perform lineup optimization.