sleeper_api 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/CLAUDE.md +3 -1
- data/lib/sleeper_api/client.rb +46 -19
- data/lib/sleeper_api/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 49f189b10709caa46c846f8733372cfd50d1dff0f66548aba5cb7ce0d32508f5
|
|
4
|
+
data.tar.gz: a0670835fa5f56541d041292b498722d0597a0599c724e95f9e3ed193151872c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dd18ff49145f5c1848857f7af5e9b15f02a8aac6f7940fe85517d333a213707f524d3f54d5d211ce94de28be9e955e6e366a3db66101ce329d39264f6eabf983
|
|
7
|
+
data.tar.gz: 0b254fa2078732333ee53f3f1074f3700c85c28733478234cd3c303b6b2698967889ad2db33d9802b1a93d00d7dee378387bfdb1d18403f55d0104daedc934b1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [1.2.0] - 2026-08-23
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- `Client#schedule(season, season_type:, sport:)` — a season's game list, each entry `{status, date, home, away, week, game_id}`. A team's bye week is the week it appears in no game, which derives exactly: checked against 2024, 2025 and 2026, every one gives exactly one bye per team. Note `pre` (weeks 1-3) and `post` (weeks 1-4) restart week numbering, so games from different season types must never be pooled, and a season Sleeper has not scheduled yet answers 200 with `[]` rather than 404.
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **`base_uri` is now the bare host, `https://api.sleeper.app`, and every path carries its own `/v1`.** The schedule endpoint is served from the host root, so while the version lived in `base_uri` it was unreachable at any path a caller could pass to `make_request`. Moving the version into the paths means one mechanism for every endpoint rather than an escape hatch for the exceptions.
|
|
10
|
+
|
|
11
|
+
**This changes the text of `SleeperApi::Error`**, which quotes the path it failed on: `"Failed to fetch /user/x: 404"` is now `"Failed to fetch /v1/user/x: 404"`. Anything matching on that string needs updating — though matching on it was never sound, since the same error covers a missing user, a 5xx and a timeout alike.
|
|
12
|
+
|
|
1
13
|
## [1.1.0] - 2026-08-22
|
|
2
14
|
|
|
3
15
|
### Fixed
|
data/CLAUDE.md
CHANGED
|
@@ -26,7 +26,9 @@ CI (`.github/workflows/ci.yml`) runs `bundle exec rake ci` on Ruby 3.2 only. The
|
|
|
26
26
|
Four layers, with a deliberate split between HTTP and modeling:
|
|
27
27
|
|
|
28
28
|
- **`SleeperApi`** (`lib/sleeper_api.rb`) — module-level config + memoized global `SleeperApi.client`. `Configuration` validates `timeout` (10–60) and `retries` (0–5), raising `SleeperApi::Error` outside those bounds.
|
|
29
|
-
- **`Client`** — the only thing that talks HTTP. `include HTTParty` with `base_uri "https://api.sleeper.app
|
|
29
|
+
- **`Client`** — the only thing that talks HTTP. `include HTTParty` with `base_uri "https://api.sleeper.app"` — **the bare host; the `/v1` lives in each path**. That is deliberate and load-bearing: not every Sleeper endpoint is versioned. `/schedule/{sport}/{season_type}/{season}` is served from the host root, and while `base_uri` carried the version that endpoint was unreachable at any path a caller could pass in. A new endpoint spells out where it lives; do not move the version back into `base_uri` to shorten the paths.
|
|
30
|
+
|
|
31
|
+
Every call funnels through the private `make_request`, which handles retry-on-timeout, logging, and converts non-2xx into `SleeperApi::Error`. **That error quotes the path**, so the path prefix is part of a public string — v1.2.0 changed it from `"Failed to fetch /user/x: 404"` to `"Failed to fetch /v1/user/x: 404"`. `Client` also owns the 24-hour in-memory player cache.
|
|
30
32
|
- **`League` / `User` / `Draft`** — resource objects. Each takes `(id, client)`, fetches eagerly in the constructor, memoizes into ivars, and exposes formatted hashes.
|
|
31
33
|
- **`Helpers`** — mixed into all four. `deep_symbolize_keys` plus `player_details`, which reaches through `@client` — so any class including it must define `@client`.
|
|
32
34
|
|
data/lib/sleeper_api/client.rb
CHANGED
|
@@ -15,7 +15,11 @@ module SleeperApi
|
|
|
15
15
|
include Helpers
|
|
16
16
|
include HTTParty
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
# The host only. The API version belongs in the paths because not every
|
|
19
|
+
# endpoint has one: /schedule is served from the root, and while base_uri
|
|
20
|
+
# carried "/v1" that endpoint was unreachable at any path a caller could
|
|
21
|
+
# pass to make_request.
|
|
22
|
+
base_uri "https://api.sleeper.app"
|
|
19
23
|
|
|
20
24
|
# @param config [SleeperApi::Configuration] Client configuration
|
|
21
25
|
def initialize(config)
|
|
@@ -57,7 +61,7 @@ module SleeperApi
|
|
|
57
61
|
# @return [Hash] Raw user data
|
|
58
62
|
# @see https://docs.sleeper.com/#user
|
|
59
63
|
def get_user(identifier)
|
|
60
|
-
make_request("/user/#{identifier}")
|
|
64
|
+
make_request("/v1/user/#{identifier}")
|
|
61
65
|
end
|
|
62
66
|
|
|
63
67
|
# Get leagues for a user in a specific season.
|
|
@@ -68,7 +72,7 @@ module SleeperApi
|
|
|
68
72
|
# @return [Array<Hash>] League data
|
|
69
73
|
# @see https://docs.sleeper.com/#get-all-leagues-for-user
|
|
70
74
|
def get_user_leagues(user_id, sport: "nfl", season: Time.now.year)
|
|
71
|
-
make_request("/user/#{user_id}/leagues/#{sport}/#{season}")
|
|
75
|
+
make_request("/v1/user/#{user_id}/leagues/#{sport}/#{season}")
|
|
72
76
|
end
|
|
73
77
|
|
|
74
78
|
# Get drafts for a user in a specific season.
|
|
@@ -79,7 +83,7 @@ module SleeperApi
|
|
|
79
83
|
# @return [Array<Hash>] Draft data
|
|
80
84
|
# @see https://docs.sleeper.com/#get-all-drafts-for-user
|
|
81
85
|
def get_user_drafts(user_id, sport: "nfl", season: Time.now.year)
|
|
82
|
-
make_request("/user/#{user_id}/drafts/#{sport}/#{season}")
|
|
86
|
+
make_request("/v1/user/#{user_id}/drafts/#{sport}/#{season}")
|
|
83
87
|
end
|
|
84
88
|
|
|
85
89
|
# Fetch league details.
|
|
@@ -88,7 +92,7 @@ module SleeperApi
|
|
|
88
92
|
# @return [Hash] League metadata
|
|
89
93
|
# @see https://docs.sleeper.com/#get-a-specific-league
|
|
90
94
|
def get_league(league_id)
|
|
91
|
-
make_request("/league/#{league_id}")
|
|
95
|
+
make_request("/v1/league/#{league_id}")
|
|
92
96
|
end
|
|
93
97
|
|
|
94
98
|
# Get all rosters in a league.
|
|
@@ -97,7 +101,7 @@ module SleeperApi
|
|
|
97
101
|
# @return [Array<Hash>] Roster data
|
|
98
102
|
# @see https://docs.sleeper.com/#getting-rosters-in-a-league
|
|
99
103
|
def get_league_rosters(league_id)
|
|
100
|
-
make_request("/league/#{league_id}/rosters")
|
|
104
|
+
make_request("/v1/league/#{league_id}/rosters")
|
|
101
105
|
end
|
|
102
106
|
|
|
103
107
|
# Get all users in a league.
|
|
@@ -106,7 +110,7 @@ module SleeperApi
|
|
|
106
110
|
# @return [Array<Hash>] User data
|
|
107
111
|
# @see https://docs.sleeper.com/#getting-users-in-a-league
|
|
108
112
|
def get_league_users(league_id)
|
|
109
|
-
make_request("/league/#{league_id}/users")
|
|
113
|
+
make_request("/v1/league/#{league_id}/users")
|
|
110
114
|
end
|
|
111
115
|
|
|
112
116
|
# Get matchups for a specific week.
|
|
@@ -116,7 +120,7 @@ module SleeperApi
|
|
|
116
120
|
# @return [Array<Hash>] Matchup data
|
|
117
121
|
# @see https://docs.sleeper.com/#getting-matchups-in-a-league
|
|
118
122
|
def get_league_matchups(league_id, week)
|
|
119
|
-
make_request("/league/#{league_id}/matchups/#{week}")
|
|
123
|
+
make_request("/v1/league/#{league_id}/matchups/#{week}")
|
|
120
124
|
end
|
|
121
125
|
|
|
122
126
|
# Get playoff winners bracket.
|
|
@@ -125,7 +129,7 @@ module SleeperApi
|
|
|
125
129
|
# @return [Array<Hash>] Bracket matchups
|
|
126
130
|
# @see https://docs.sleeper.com/#getting-the-playoff-bracket
|
|
127
131
|
def get_playoff_bracket(league_id)
|
|
128
|
-
make_request("/league/#{league_id}/winners_bracket")
|
|
132
|
+
make_request("/v1/league/#{league_id}/winners_bracket")
|
|
129
133
|
end
|
|
130
134
|
|
|
131
135
|
# Get toilet bowl (losers bracket).
|
|
@@ -134,7 +138,7 @@ module SleeperApi
|
|
|
134
138
|
# @return [Array<Hash>] Bracket matchups
|
|
135
139
|
# @see https://docs.sleeper.com/#getting-the-playoff-bracket
|
|
136
140
|
def get_toilet_bowl(league_id)
|
|
137
|
-
make_request("/league/#{league_id}/losers_bracket")
|
|
141
|
+
make_request("/v1/league/#{league_id}/losers_bracket")
|
|
138
142
|
end
|
|
139
143
|
|
|
140
144
|
# Get transactions for a specific week.
|
|
@@ -144,7 +148,7 @@ module SleeperApi
|
|
|
144
148
|
# @return [Array<Hash>] Transaction data
|
|
145
149
|
# @see https://docs.sleeper.com/#get-transactions
|
|
146
150
|
def get_transactions(league_id, week)
|
|
147
|
-
make_request("/league/#{league_id}/transactions/#{week}")
|
|
151
|
+
make_request("/v1/league/#{league_id}/transactions/#{week}")
|
|
148
152
|
end
|
|
149
153
|
|
|
150
154
|
# Get league drafts.
|
|
@@ -153,7 +157,7 @@ module SleeperApi
|
|
|
153
157
|
# @return [Array<Hash>] Draft data
|
|
154
158
|
# @see https://docs.sleeper.com/#get-all-drafts-for-a-league
|
|
155
159
|
def get_league_drafts(league_id)
|
|
156
|
-
make_request("/league/#{league_id}/drafts")
|
|
160
|
+
make_request("/v1/league/#{league_id}/drafts")
|
|
157
161
|
end
|
|
158
162
|
|
|
159
163
|
# Get traded draft picks for a league.
|
|
@@ -162,7 +166,7 @@ module SleeperApi
|
|
|
162
166
|
# @return [Array<Hash>] Traded picks
|
|
163
167
|
# @see https://docs.sleeper.com/#get-traded-picks-in-a-draft
|
|
164
168
|
def get_league_traded_picks(league_id)
|
|
165
|
-
make_request("/league/#{league_id}/traded_picks")
|
|
169
|
+
make_request("/v1/league/#{league_id}/traded_picks")
|
|
166
170
|
end
|
|
167
171
|
|
|
168
172
|
# Fetch draft details.
|
|
@@ -171,7 +175,7 @@ module SleeperApi
|
|
|
171
175
|
# @return [Hash] Draft metadata
|
|
172
176
|
# @see https://docs.sleeper.com/#get-a-specific-draft
|
|
173
177
|
def get_draft(draft_id)
|
|
174
|
-
make_request("/draft/#{draft_id}")
|
|
178
|
+
make_request("/v1/draft/#{draft_id}")
|
|
175
179
|
end
|
|
176
180
|
|
|
177
181
|
# Get draft picks.
|
|
@@ -180,7 +184,7 @@ module SleeperApi
|
|
|
180
184
|
# @return [Array<Hash>] Pick data
|
|
181
185
|
# @see https://docs.sleeper.com/#get-all-picks-in-a-draft
|
|
182
186
|
def get_draft_picks(draft_id)
|
|
183
|
-
make_request("/draft/#{draft_id}/picks")
|
|
187
|
+
make_request("/v1/draft/#{draft_id}/picks")
|
|
184
188
|
end
|
|
185
189
|
|
|
186
190
|
# Get traded draft picks for a draft.
|
|
@@ -189,7 +193,7 @@ module SleeperApi
|
|
|
189
193
|
# @return [Array<Hash>] Traded picks
|
|
190
194
|
# @see https://docs.sleeper.com/#get-traded-picks-in-a-draft
|
|
191
195
|
def get_draft_traded_picks(draft_id)
|
|
192
|
-
make_request("/draft/#{draft_id}/traded_picks")
|
|
196
|
+
make_request("/v1/draft/#{draft_id}/traded_picks")
|
|
193
197
|
end
|
|
194
198
|
|
|
195
199
|
# Get NFL state (week, season status).
|
|
@@ -198,13 +202,36 @@ module SleeperApi
|
|
|
198
202
|
# @return [Hash] State data
|
|
199
203
|
# @see https://docs.sleeper.com/#get-nfl-state
|
|
200
204
|
def get_nfl_state(sport = "nfl")
|
|
201
|
-
nfl_state = make_request("/state/#{sport}")
|
|
205
|
+
nfl_state = make_request("/v1/state/#{sport}")
|
|
202
206
|
nfl_state.each_with_object({}) do |(k, v), result|
|
|
203
207
|
key = k.is_a?(String) ? k.to_sym : k
|
|
204
208
|
result[key] = v
|
|
205
209
|
end
|
|
206
210
|
end
|
|
207
211
|
|
|
212
|
+
# Get a season's game schedule.
|
|
213
|
+
#
|
|
214
|
+
# Undocumented, and served from the host root rather than /v1 — hence the
|
|
215
|
+
# version living in the paths rather than in base_uri.
|
|
216
|
+
#
|
|
217
|
+
# Returns a flat array of games, each `{status, date, home, away, week,
|
|
218
|
+
# game_id}`. A team's bye week is the week it appears in no game; that
|
|
219
|
+
# derives exactly, but only within one season type — `pre` (weeks 1-3) and
|
|
220
|
+
# `post` (weeks 1-4) restart week numbering, so games from different season
|
|
221
|
+
# types must never be pooled.
|
|
222
|
+
#
|
|
223
|
+
# A season Sleeper has not scheduled yet answers 200 with an empty array
|
|
224
|
+
# rather than 404, so an empty result is a legitimate answer and not an
|
|
225
|
+
# error.
|
|
226
|
+
#
|
|
227
|
+
# @param season [Integer, String] Season year, e.g. 2026
|
|
228
|
+
# @param season_type [String] "regular" (default), "pre", or "post"
|
|
229
|
+
# @param sport [String] Sport code (default: "nfl")
|
|
230
|
+
# @return [HTTParty::Response] Array of games
|
|
231
|
+
def schedule(season, season_type: "regular", sport: "nfl")
|
|
232
|
+
make_request("/schedule/#{sport}/#{season_type}/#{season}")
|
|
233
|
+
end
|
|
234
|
+
|
|
208
235
|
# Get trending players.
|
|
209
236
|
#
|
|
210
237
|
# @param sport [String] Sport code (default: "nfl")
|
|
@@ -214,7 +241,7 @@ module SleeperApi
|
|
|
214
241
|
# @return [Array<Hash>] Trending players
|
|
215
242
|
# @see https://docs.sleeper.com/#trending-players
|
|
216
243
|
def trending_players(sport = "nfl", type: "add", lookback_hours: 24, limit: 25)
|
|
217
|
-
make_request("/players/#{sport}/trending/#{type}?lookback_hours=#{lookback_hours}&limit=#{limit}")
|
|
244
|
+
make_request("/v1/players/#{sport}/trending/#{type}?lookback_hours=#{lookback_hours}&limit=#{limit}")
|
|
218
245
|
end
|
|
219
246
|
|
|
220
247
|
# Get all player data (cached for 24 hours).
|
|
@@ -225,7 +252,7 @@ module SleeperApi
|
|
|
225
252
|
def get_players(sport = "nfl")
|
|
226
253
|
return @players_cache if @players_cache && @cache_timestamp && (Time.now - @cache_timestamp) < (3600 * 24)
|
|
227
254
|
|
|
228
|
-
response = make_request("/players/#{sport}")
|
|
255
|
+
response = make_request("/v1/players/#{sport}")
|
|
229
256
|
@players_cache = response.parsed_response
|
|
230
257
|
@cache_timestamp = Time.now
|
|
231
258
|
|
data/lib/sleeper_api/version.rb
CHANGED