-
Notifications
You must be signed in to change notification settings - Fork 7
/
api.R
84 lines (83 loc) · 2.98 KB
/
api.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#' Call the ESPN Fantasy API
#'
#' Use [httr::GET()] to make a request to the ESPN API and return the parsed
#' list from the JSON data. The function uses [httr::RETRY()], so the call will
#' repeat up to three times if there is a failure.
#'
#' @inheritParams ffl_id
#' @param view Character vector of specific API "views" which describe the data
#' returned (e.g., "mRoster", "mSettings").
#' @param leagueHistory logical; Should the `leagueHistory` version of the API
#' be called? If `TRUE`, a list of results is returned, with one element for
#' each historical year of the league.
#' @param seasonId Integer year of NFL season. By default, the season is
#' currently set to 2023. Use a recent year or set `leagueHistory` to `TRUE`
#' to obtain all past data.
#' @param scoringPeriodId Integer week of NFL season. By default, `NULL` will
#' use the current week (see [ffl_week()]). Scoring periods are always one
#' week in length, whereas matchups might be longer.
#' @param ... Additional queries passed to [httr::GET()]. Arguments are
#' converted to a named list and passed to `query` alongside `view`.
#' @examples
#' \dontrun{
#' ffl_api()
#' }
#' @return A single JSON string.
#' @importFrom httr RETRY accept_json add_headers user_agent http_type content
#' http_error status_code
#' @importFrom jsonlite fromJSON
#' @keywords internal
#' @export
ffl_api <- function(leagueId = ffl_id(), view = NULL, leagueHistory = FALSE,
seasonId = 2024, scoringPeriodId = NULL, ...) {
dots <- list(..., scoringPeriodId = scoringPeriodId)
age_path <- ifelse(
test = isTRUE(leagueHistory),
yes = "leagueHistory",
no = sprintf("seasons/%i/segments/0/leagues", seasonId)
)
view <- as.list(view)
names(view) <- rep("view", length(view))
if (!is.null(names(dots))) {
view <- c(view, dots)
}
try_json(
url = "https://lm-api-reads.fantasy.espn.com",
path = paste("apis/v3/games/ffl", age_path, leagueId, sep = "/"),
query = view,
leagueHistory = leagueHistory
)
}
try_json <- function(url, path = "", query = NULL, leagueHistory = NULL) {
resp <- httr::RETRY(
verb = "GET",
url = ifelse(
test = is.null(path) | !nzchar(path),
yes = url,
paste(url, paste(path, collapse = "/"), sep = "/")
),
query = query,
httr::accept_json(),
httr::user_agent("https://github.com/k5cents/fflr/"),
terminate_on = c(400:417)
)
if (httr::http_type(resp) != "application/json") {
stop("API did not return JSON", call. = FALSE)
}
raw <- httr::content(resp, as = "text", encoding = "UTF-8")
parsed <- jsonlite::fromJSON(raw)
if (httr::http_error(resp) && any(grepl("message", names(parsed)))) {
if (!is.null(leagueHistory) && isTRUE(leagueHistory)) {
parsed$message <- paste(parsed$message, "(No League History?)")
}
stop(
sprintf(
"ESPN Fantasy API request failed [%s]\n%s",
httr::status_code(resp), parsed$message
),
call. = FALSE
)
} else {
return(parsed)
}
}