nhl-api-py 3.2.3__tar.gz → 3.3.0__tar.gz

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.
Files changed (43) hide show
  1. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/PKG-INFO +1 -1
  2. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/edge.py +195 -0
  3. nhl_api_py-3.3.0/nhlpy/api/game_center.py +214 -0
  4. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/helpers.py +63 -12
  5. nhl_api_py-3.3.0/nhlpy/api/misc.py +108 -0
  6. nhl_api_py-3.3.0/nhlpy/api/players.py +68 -0
  7. nhl_api_py-3.3.0/nhlpy/api/schedule.py +302 -0
  8. nhl_api_py-3.3.0/nhlpy/api/standings.py +94 -0
  9. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/stats.py +100 -0
  10. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/teams.py +71 -19
  11. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/pyproject.toml +1 -1
  12. nhl_api_py-3.2.3/nhlpy/api/game_center.py +0 -100
  13. nhl_api_py-3.2.3/nhlpy/api/misc.py +0 -52
  14. nhl_api_py-3.2.3/nhlpy/api/players.py +0 -35
  15. nhl_api_py-3.2.3/nhlpy/api/schedule.py +0 -164
  16. nhl_api_py-3.2.3/nhlpy/api/standings.py +0 -65
  17. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/LICENSE +0 -0
  18. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/README.md +0 -0
  19. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/__init__.py +0 -0
  20. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/__init__.py +0 -0
  21. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/__init__.py +0 -0
  22. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/builder.py +0 -0
  23. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/__init__.py +0 -0
  24. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/decision.py +0 -0
  25. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/draft.py +0 -0
  26. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/experience.py +0 -0
  27. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/franchise.py +0 -0
  28. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/game_type.py +0 -0
  29. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/home_road.py +0 -0
  30. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/nationality.py +0 -0
  31. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/opponent.py +0 -0
  32. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/position.py +0 -0
  33. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/season.py +0 -0
  34. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/shoot_catch.py +0 -0
  35. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/status.py +0 -0
  36. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/sorting/__init__.py +0 -0
  37. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/sorting/sorting_options.py +0 -0
  38. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/config.py +0 -0
  39. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/data/seasonal_information_manifest.json +0 -0
  40. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/data/team_stat_ids.json +0 -0
  41. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/data/teams_20232024.json +0 -0
  42. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/http_client.py +0 -0
  43. {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/nhl_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nhl-api-py
3
- Version: 3.2.3
3
+ Version: 3.3.0
4
4
  Summary: NHL API (Updated for 2025/2026) and EDGE Stats. For standings, team stats, outcomes, player information. Contains each individual API endpoint as well as convience methods as well as pythonic query builder for more indepth EDGE stats.
5
5
  Home-page: https://github.com/coreyjs/nhl-api-py
6
6
  License: Apache-2.0
@@ -27,6 +27,19 @@ class Edge:
27
27
  Returns:
28
28
  dict: Dictionary containing detailed EDGE statistics for the skater
29
29
 
30
+ Key Response Fields:
31
+ player.firstName.default (str): Player first name
32
+ player.lastName.default (str): Player last name
33
+ player.goals (int): Total goals scored
34
+ player.points (int): Total points
35
+ topShotSpeed.imperial (float): Top shot speed in mph
36
+ skatingSpeed.speedMax.imperial (float): Maximum skating speed in mph
37
+ totalDistanceSkated.imperial (float): Total distance skated in miles
38
+ zoneTimeDetails.offensiveZonePctg (float): Offensive zone time percentage
39
+
40
+ Response Docs:
41
+ docs/edge.md
42
+
30
43
  Example:
31
44
  client.edge.skater_detail(player_id=8478402)
32
45
  client.edge.skater_detail(player_id=8478402, season=20232024, game_type=2)
@@ -47,6 +60,14 @@ class Edge:
47
60
 
48
61
  Returns:
49
62
  dict: Shot speed statistics including maximum and average speeds
63
+
64
+ Key Response Fields:
65
+ shotSpeedData (list): Shot speed entries with percentiles
66
+ topShotSpeed.imperial (float): Top shot speed in mph
67
+ averageShotSpeed.imperial (float): Average shot speed in mph
68
+
69
+ Response Docs:
70
+ docs/edge.md
50
71
  """
51
72
  if season is None:
52
73
  resource = f"edge/skater-shot-speed-detail/{player_id}/now"
@@ -64,6 +85,14 @@ class Edge:
64
85
 
65
86
  Returns:
66
87
  dict: Skating speed statistics including burst speed and average speed
88
+
89
+ Key Response Fields:
90
+ skatingSpeedData (list): Skating speed entries with burst counts
91
+ speedMax.imperial (float): Maximum skating speed in mph
92
+ burstCount (int): Number of speed bursts
93
+
94
+ Response Docs:
95
+ docs/edge.md
67
96
  """
68
97
  if season is None:
69
98
  resource = f"edge/skater-skating-speed-detail/{player_id}/now"
@@ -81,6 +110,14 @@ class Edge:
81
110
 
82
111
  Returns:
83
112
  dict: Shot location data including shooting patterns and heat maps
113
+
114
+ Key Response Fields:
115
+ shotLocations (list): Shot data grouped by area
116
+ area (str): Ice zone identifier
117
+ shotCount (int): Number of shots from each area
118
+
119
+ Response Docs:
120
+ docs/edge.md
84
121
  """
85
122
  if season is None:
86
123
  resource = f"edge/skater-shot-location-detail/{player_id}/now"
@@ -98,6 +135,14 @@ class Edge:
98
135
 
99
136
  Returns:
100
137
  dict: Distance traveled statistics per game and per shift
138
+
139
+ Key Response Fields:
140
+ distanceData (list): Distance entries per game
141
+ totalDistance.imperial (float): Total distance skated in miles
142
+ gameMax.imperial (float): Maximum distance skated in a single game in miles
143
+
144
+ Response Docs:
145
+ docs/edge.md
101
146
  """
102
147
  if season is None:
103
148
  resource = f"edge/skater-skating-distance-detail/{player_id}/now"
@@ -115,6 +160,14 @@ class Edge:
115
160
 
116
161
  Returns:
117
162
  dict: Comparison data relative to league averages
163
+
164
+ Key Response Fields:
165
+ comparisonData (list): Comparison metrics vs league
166
+ leagueAverage (float): League average value for each metric
167
+ playerValue (float): Player value for each metric
168
+
169
+ Response Docs:
170
+ docs/edge.md
118
171
  """
119
172
  if season is None:
120
173
  resource = f"edge/skater-comparison/{player_id}/now"
@@ -132,6 +185,14 @@ class Edge:
132
185
 
133
186
  Returns:
134
187
  dict: Time spent in offensive, defensive, and neutral zones
188
+
189
+ Key Response Fields:
190
+ offensiveZonePctg (float): Offensive zone time percentage
191
+ defensiveZonePctg (float): Defensive zone time percentage
192
+ neutralZonePctg (float): Neutral zone time percentage
193
+
194
+ Response Docs:
195
+ docs/edge.md
135
196
  """
136
197
  if season is None:
137
198
  resource = f"edge/skater-zone-time/{player_id}/now"
@@ -150,6 +211,14 @@ class Edge:
150
211
 
151
212
  Returns:
152
213
  dict: Overview of league-wide skater EDGE statistics
214
+
215
+ Key Response Fields:
216
+ leaders.hardestShot (list): League leaders for hardest shot
217
+ leaders.maxSkatingSpeed (list): League leaders for max skating speed
218
+ leaders.totalDistanceSkated (list): League leaders for total distance skated
219
+
220
+ Response Docs:
221
+ docs/edge.md
153
222
  """
154
223
  if season is None:
155
224
  resource = "edge/skater-landing/now"
@@ -167,6 +236,14 @@ class Edge:
167
236
 
168
237
  Returns:
169
238
  dict: CAT EDGE statistics for the skater
239
+
240
+ Key Response Fields:
241
+ player (dict): Compact player summary with EDGE highlights
242
+ shotSpeed (dict): Condensed shot speed data
243
+ skatingSpeed (dict): Condensed skating speed data
244
+
245
+ Response Docs:
246
+ docs/edge.md
170
247
  """
171
248
  if season is None:
172
249
  resource = f"cat/edge/skater-detail/{player_id}/now"
@@ -194,6 +271,16 @@ class Edge:
194
271
  Returns:
195
272
  dict: Dictionary containing detailed EDGE statistics for the goalie
196
273
 
274
+ Key Response Fields:
275
+ player.wins (int): Total wins
276
+ player.savePctg (float): Overall save percentage
277
+ stats.goalsAgainstAvg.value (float): Goals against average
278
+ stats.gamesAbove900.value (float): Games with save pct above .900
279
+ shotLocationSummary (list): Save data grouped by shot area
280
+
281
+ Response Docs:
282
+ docs/edge.md
283
+
197
284
  Example:
198
285
  client.edge.goalie_detail(player_id=8476945)
199
286
  client.edge.goalie_detail(player_id=8476945, season=20232024, game_type=2)
@@ -214,6 +301,14 @@ class Edge:
214
301
 
215
302
  Returns:
216
303
  dict: Shot location data faced by the goalie including save percentages by zone
304
+
305
+ Key Response Fields:
306
+ shotLocations (list): Save data grouped by shot location
307
+ area (str): Ice zone identifier
308
+ savePctg (float): Save percentage for each area
309
+
310
+ Response Docs:
311
+ docs/edge.md
217
312
  """
218
313
  if season is None:
219
314
  resource = f"edge/goalie-shot-location-detail/{player_id}/now"
@@ -231,6 +326,14 @@ class Edge:
231
326
 
232
327
  Returns:
233
328
  dict: 5-on-5 performance statistics and save percentages
329
+
330
+ Key Response Fields:
331
+ fiveOnFiveStats (dict): 5-on-5 performance metrics
332
+ savePctg5v5 (float): Save percentage at 5-on-5
333
+ goalsAgainstAvg5v5 (float): Goals against average at 5-on-5
334
+
335
+ Response Docs:
336
+ docs/edge.md
234
337
  """
235
338
  if season is None:
236
339
  resource = f"edge/goalie-5v5-detail/{player_id}/now"
@@ -248,6 +351,14 @@ class Edge:
248
351
 
249
352
  Returns:
250
353
  dict: Comparison data relative to league averages
354
+
355
+ Key Response Fields:
356
+ comparisonData (list): Comparison metrics vs league
357
+ leagueAverage (float): League average value for each metric
358
+ playerValue (float): Player value for each metric
359
+
360
+ Response Docs:
361
+ docs/edge.md
251
362
  """
252
363
  if season is None:
253
364
  resource = f"edge/goalie-comparison/{player_id}/now"
@@ -265,6 +376,14 @@ class Edge:
265
376
 
266
377
  Returns:
267
378
  dict: Detailed save percentage breakdowns by situation and location
379
+
380
+ Key Response Fields:
381
+ savePctgBreakdown (list): Save percentage by situation type
382
+ overallSavePctg (float): Overall save percentage
383
+ highDangerSavePctg (float): Save percentage on high-danger chances
384
+
385
+ Response Docs:
386
+ docs/edge.md
268
387
  """
269
388
  if season is None:
270
389
  resource = f"edge/goalie-save-percentage-detail/{player_id}/now"
@@ -283,6 +402,14 @@ class Edge:
283
402
 
284
403
  Returns:
285
404
  dict: Overview of league-wide goalie EDGE statistics
405
+
406
+ Key Response Fields:
407
+ leaders (dict): League leaders for goalie EDGE stats
408
+ topSavePctg (list): Leaders by save percentage
409
+ topGamesAbove900 (list): Leaders by games above .900
410
+
411
+ Response Docs:
412
+ docs/edge.md
286
413
  """
287
414
  if season is None:
288
415
  resource = "edge/goalie-landing/now"
@@ -300,6 +427,14 @@ class Edge:
300
427
 
301
428
  Returns:
302
429
  dict: CAT EDGE statistics for the goalie
430
+
431
+ Key Response Fields:
432
+ player (dict): Compact goalie summary with EDGE highlights
433
+ savePctg (float): Condensed save percentage data
434
+ goalsAgainstAvg (float): Condensed goals against average
435
+
436
+ Response Docs:
437
+ docs/edge.md
303
438
  """
304
439
  if season is None:
305
440
  resource = f"cat/edge/goalie-detail/{player_id}/now"
@@ -327,6 +462,18 @@ class Edge:
327
462
  Returns:
328
463
  dict: Dictionary containing detailed EDGE statistics for the team
329
464
 
465
+ Key Response Fields:
466
+ team.abbrev (str): Team abbreviation
467
+ team.wins (int): Total wins
468
+ team.points (int): Total points
469
+ shotSpeed.topShotSpeed.imperial (float): Top shot speed in mph
470
+ skatingSpeed.speedMax.imperial (float): Maximum skating speed in mph
471
+ distanceSkated.total.imperial (float): Total distance skated in miles
472
+ zoneTimeDetails.offensiveZonePctg (float): Offensive zone time percentage
473
+
474
+ Response Docs:
475
+ docs/edge.md
476
+
330
477
  Example:
331
478
  client.edge.team_detail(team_id=10)
332
479
  client.edge.team_detail(team_id=10, season=20232024, game_type=2)
@@ -347,6 +494,14 @@ class Edge:
347
494
 
348
495
  Returns:
349
496
  dict: Team skating distance statistics per game and per player
497
+
498
+ Key Response Fields:
499
+ distanceData (list): Distance entries per game and per player
500
+ totalDistance.imperial (float): Total team distance skated in miles
501
+ perGameAvg.imperial (float): Average distance per game in miles
502
+
503
+ Response Docs:
504
+ docs/edge.md
350
505
  """
351
506
  if season is None:
352
507
  resource = f"edge/team-skating-distance-detail/{team_id}/now"
@@ -364,6 +519,14 @@ class Edge:
364
519
 
365
520
  Returns:
366
521
  dict: Team time spent in offensive, defensive, and neutral zones
522
+
523
+ Key Response Fields:
524
+ offensiveZonePctg (float): Offensive zone time percentage
525
+ defensiveZonePctg (float): Defensive zone time percentage
526
+ neutralZonePctg (float): Neutral zone time percentage
527
+
528
+ Response Docs:
529
+ docs/edge.md
367
530
  """
368
531
  if season is None:
369
532
  resource = f"edge/team-zone-time-details/{team_id}/now"
@@ -381,6 +544,14 @@ class Edge:
381
544
 
382
545
  Returns:
383
546
  dict: Team shot location data including shooting patterns and heat maps
547
+
548
+ Key Response Fields:
549
+ shotLocations (list): Shot data grouped by area
550
+ area (str): Ice zone identifier
551
+ shotCount (int): Number of shots from each area
552
+
553
+ Response Docs:
554
+ docs/edge.md
384
555
  """
385
556
  if season is None:
386
557
  resource = f"edge/team-shot-location-detail/{team_id}/now"
@@ -399,6 +570,14 @@ class Edge:
399
570
 
400
571
  Returns:
401
572
  dict: Overview of league-wide team EDGE statistics
573
+
574
+ Key Response Fields:
575
+ leaders (dict): Team EDGE leaders across categories
576
+ topShotSpeed (list): Leaders by team shot speed
577
+ topSkatingSpeed (list): Leaders by team skating speed
578
+
579
+ Response Docs:
580
+ docs/edge.md
402
581
  """
403
582
  if season is None:
404
583
  resource = "edge/team-landing/now"
@@ -416,6 +595,14 @@ class Edge:
416
595
 
417
596
  Returns:
418
597
  dict: Team shot speed statistics including maximum and average speeds
598
+
599
+ Key Response Fields:
600
+ shotSpeedData (list): Shot speed entries by player
601
+ topShotSpeed.imperial (float): Top team shot speed in mph
602
+ averageShotSpeed.imperial (float): Average team shot speed in mph
603
+
604
+ Response Docs:
605
+ docs/edge.md
419
606
  """
420
607
  if season is None:
421
608
  resource = f"edge/team-shot-speed-detail/{team_id}/now"
@@ -433,6 +620,14 @@ class Edge:
433
620
 
434
621
  Returns:
435
622
  dict: Team skating speed statistics including burst speed and average speed
623
+
624
+ Key Response Fields:
625
+ skatingSpeedData (list): Skating speed entries by player
626
+ speedMax.imperial (float): Maximum team skating speed in mph
627
+ averageSpeed.imperial (float): Average team skating speed in mph
628
+
629
+ Response Docs:
630
+ docs/edge.md
436
631
  """
437
632
  if season is None:
438
633
  resource = f"edge/team-skating-speed-detail/{team_id}/now"
@@ -0,0 +1,214 @@
1
+ from typing import Optional, List
2
+ from nhlpy.http_client import HttpClient, Endpoint
3
+
4
+
5
+ class GameCenter:
6
+ def __init__(self, http_client: HttpClient):
7
+ self.client = http_client
8
+
9
+ def boxscore(self, game_id: str) -> dict:
10
+ """Get the full boxscore for a specific NHL game, including team scores, shots on goal,
11
+ and per-player stats broken down by position. Game IDs can be retrieved from the schedule endpoint.
12
+
13
+ Args:
14
+ game_id (str): The unique game identifier (e.g. "2023020280").
15
+
16
+ Key Response Fields:
17
+ gameState (str): Current state of the game ("FUT", "LIVE", "OFF", "FINAL").
18
+ awayTeam.abbrev (str): Away team abbreviation (e.g. "TOR").
19
+ awayTeam.score (int): Away team total goals.
20
+ homeTeam.abbrev (str): Home team abbreviation (e.g. "BOS").
21
+ homeTeam.score (int): Home team total goals.
22
+ awayTeam.sog (int): Away team shots on goal.
23
+ homeTeam.sog (int): Home team shots on goal.
24
+ playerByGameStats.awayTeam.forwards (list): Per-player stats for away forwards.
25
+ gameOutcome.lastPeriodType (str): Period type the game ended in ("REG", "OT", "SO").
26
+
27
+ Response Docs:
28
+ See ``docs/game_center.md`` for the complete response schema.
29
+
30
+ Example:
31
+ client.game_center.boxscore(game_id="2023020280")
32
+
33
+ Returns:
34
+ dict: Full boxscore data including team totals and player-level game stats.
35
+ """
36
+ return self.client.get(endpoint=Endpoint.API_WEB_V1, resource=f"gamecenter/{game_id}/boxscore").json()
37
+
38
+ def play_by_play(self, game_id: str) -> dict:
39
+ """Get the full play-by-play feed for a specific NHL game, containing every recorded event
40
+ such as shots, goals, faceoffs, hits, and penalties. Game IDs can be retrieved from the
41
+ schedule endpoint.
42
+
43
+ Args:
44
+ game_id (str): The unique game identifier (e.g. "2023020280").
45
+
46
+ Key Response Fields:
47
+ plays (list): All game events (~340 per game), ordered chronologically.
48
+ plays[].typeDescKey (str): Event type descriptor (e.g. "shot-on-goal", "goal", "faceoff").
49
+ plays[].timeInPeriod (str): Time elapsed in the period (e.g. "12:34").
50
+ plays[].periodDescriptor.number (int): Period number (1, 2, 3, 4 for OT).
51
+ plays[].details.xCoord (float): Ice x-coordinate of the event.
52
+ plays[].details.yCoord (float): Ice y-coordinate of the event.
53
+ rosterSpots (list): Player info for all rostered players in the game.
54
+
55
+ Response Docs:
56
+ See ``docs/game_center.md`` for the complete response schema.
57
+
58
+ Example:
59
+ client.game_center.play_by_play(game_id="2023020280")
60
+
61
+ Returns:
62
+ dict: Complete play-by-play data including all events and roster information.
63
+ """
64
+ return self.client.get(endpoint=Endpoint.API_WEB_V1, resource=f"gamecenter/{game_id}/play-by-play").json()
65
+
66
+ def match_up(self, game_id: str) -> dict:
67
+ """Get the landing-page summary for a specific NHL game, including scoring by period,
68
+ three-stars selections, and penalty details. Game IDs can be retrieved from the
69
+ schedule endpoint.
70
+
71
+ Args:
72
+ game_id (str): The unique game identifier (e.g. "2023020280").
73
+
74
+ Key Response Fields:
75
+ summary.scoring (list): Goals broken down by period.
76
+ summary.threeStars (list): Three stars of the game, each containing:
77
+ star (int), playerId (int), teamAbbrev (str), name (str), position (str).
78
+ summary.penalties (list): All penalties assessed during the game.
79
+ summary.teamGameStats (list): Head-to-head team stats (SOG, faceoff %, PIM, etc.).
80
+ awayTeam.abbrev (str): Away team abbreviation.
81
+ homeTeam.abbrev (str): Home team abbreviation.
82
+
83
+ Response Docs:
84
+ See ``docs/game_center.md`` for the complete response schema.
85
+
86
+ Example:
87
+ client.game_center.match_up(game_id="2023020280")
88
+
89
+ Returns:
90
+ dict: Detailed game matchup data including scoring summary, three stars, and penalties.
91
+ """
92
+ return self.client.get(endpoint=Endpoint.API_WEB_V1, resource=f"gamecenter/{game_id}/landing").json()
93
+
94
+ def daily_scores(self, date: Optional[str] = None) -> dict:
95
+ """Get scores and game states for all NHL games on a given date. Returns the current
96
+ day's scoreboard when no date is provided, along with navigation links to adjacent dates.
97
+
98
+ Args:
99
+ date (str, optional): Date in YYYY-MM-DD format (e.g. "2024-01-15").
100
+ If not provided, returns the current day's scores.
101
+
102
+ Key Response Fields:
103
+ currentDate (str): The date for the returned scores (YYYY-MM-DD).
104
+ prevDate (str): Previous date with NHL games, for pagination.
105
+ nextDate (str): Next date with NHL games, for pagination.
106
+ games (list): All games on the requested date.
107
+ games[].awayTeam.abbrev (str): Away team abbreviation (e.g. "NYR").
108
+ games[].awayTeam.score (int): Away team score.
109
+ games[].homeTeam.abbrev (str): Home team abbreviation (e.g. "PIT").
110
+ games[].homeTeam.score (int): Home team score.
111
+ games[].gameState (str): Game state ("FUT", "LIVE", "OFF", "FINAL").
112
+
113
+ Response Docs:
114
+ See ``docs/game_center.md`` for the complete response schema.
115
+
116
+ Example:
117
+ client.game_center.daily_scores(date="2024-01-15")
118
+
119
+ Returns:
120
+ dict: Scoreboard data with all games, scores, statuses, and date navigation.
121
+ """
122
+ return self.client.get(endpoint=Endpoint.API_WEB_V1, resource=f"score/{date if date else 'now'}").json()
123
+
124
+ def shift_chart_data(self, game_id: str, excludes: List[str] = None) -> dict:
125
+ """Get individual player shift data for a specific game, including start/end times and
126
+ durations for every shift. A typical game contains ~740 shift records across both teams.
127
+
128
+ Args:
129
+ game_id (str): The unique game identifier (e.g. "2023020280"). Game IDs can be
130
+ retrieved from the schedule endpoint.
131
+ excludes (List[str], optional): Fields to exclude from the response.
132
+ Defaults to ["eventDetails"] if not provided.
133
+
134
+ Key Response Fields:
135
+ data (list): All shift records (~740 per game).
136
+ data[].firstName (str): Player's first name.
137
+ data[].lastName (str): Player's last name.
138
+ data[].teamAbbrev (str): Team abbreviation for the player.
139
+ data[].period (int): Period number the shift occurred in.
140
+ data[].startTime (str): Shift start time within the period (e.g. "05:23").
141
+ data[].duration (str): Length of the shift (e.g. "00:45").
142
+ total (int): Total number of shift records returned.
143
+
144
+ Response Docs:
145
+ See ``docs/game_center.md`` for the complete response schema.
146
+
147
+ Example:
148
+ client.game_center.shift_chart_data(game_id="2023020280")
149
+
150
+ Returns:
151
+ dict: Shift chart data containing individual shift records for all players.
152
+ """
153
+ if excludes is None:
154
+ excludes = ["eventDetails"]
155
+
156
+ exclude_p: str = ",".join(excludes)
157
+ expr_p: str = f"gameId={game_id} and ((duration != '00:00' and typeCode = 517) or typeCode != 517 )"
158
+ return self.client.get(
159
+ endpoint=Endpoint.API_STATS, resource=f"en/shiftcharts?cayenneExp={expr_p}&exclude={exclude_p}"
160
+ ).json()
161
+
162
+ def season_series_matchup(self, game_id: str) -> dict:
163
+ """Get the season-series record and contextual stats for a specific game, including
164
+ head-to-head win totals, team game stats, and linescore data from the right-rail panel.
165
+
166
+ Args:
167
+ game_id (str): The unique game identifier (e.g. "2023020280"). Game IDs can be
168
+ retrieved from the schedule endpoint.
169
+
170
+ Key Response Fields:
171
+ seasonSeries (list): Results of all regular-season matchups between the two teams.
172
+ seasonSeriesWins (object): Win counts keyed by team ID.
173
+ teamGameStats (list): Comparative team stats for this game (SOG, faceoff %, etc.).
174
+ linescore (object): Period-by-period scoring breakdown.
175
+ gameReports (object): Links to official game reports (e.g. summary, event summary).
176
+
177
+ Response Docs:
178
+ See ``docs/game_center.md`` for the complete response schema.
179
+
180
+ Example:
181
+ client.game_center.season_series_matchup(game_id="2023020280")
182
+
183
+ Returns:
184
+ dict: Season series record, team game stats, linescore, and game report links.
185
+ """
186
+ return self.client.get(endpoint=Endpoint.API_WEB_V1, resource=f"gamecenter/{game_id}/right-rail").json()
187
+
188
+ def game_story(self, game_id: str) -> dict:
189
+ """Get the narrative game story for a specific game, including scoring summaries,
190
+ three-stars selections, and head-to-head team statistics. This is the data behind
191
+ the NHL's post-game recap page.
192
+
193
+ Args:
194
+ game_id (str): The unique game identifier (e.g. "2023020280"). Game IDs can be
195
+ retrieved from the schedule endpoint.
196
+
197
+ Key Response Fields:
198
+ summary.scoring (list): Goals organized by period, with scorer and assist details.
199
+ summary.threeStars (list): Three stars of the game with player info.
200
+ summary.teamGameStats (list): Comparative team stats (SOG, faceoff %, PIM, hits, etc.).
201
+ awayTeam.abbrev (str): Away team abbreviation.
202
+ homeTeam.abbrev (str): Home team abbreviation.
203
+ gameState (str): Current state of the game ("FUT", "LIVE", "OFF", "FINAL").
204
+
205
+ Response Docs:
206
+ See ``docs/game_center.md`` for the complete response schema.
207
+
208
+ Example:
209
+ client.game_center.game_story(game_id="2023020280")
210
+
211
+ Returns:
212
+ dict: Game story data with scoring summary, three stars, and team stat comparisons.
213
+ """
214
+ return self.client.get(endpoint=Endpoint.API_WEB_V1, resource=f"wsc/game-story/{game_id}").json()
@@ -21,18 +21,31 @@ class Helpers:
21
21
  return name[ntype]["default"]
22
22
 
23
23
  def game_ids_by_season(self, season: str, game_types: List[int] = None, api_sleep_rate: float = 1) -> List[str]:
24
- """Gets all game IDs for a specified season.
24
+ """Gets all game IDs for a specified season by querying every team's schedule.
25
+
26
+ Iterates over all 32 NHL teams and collects game IDs from each team's
27
+ season schedule. Expect roughly 2,600 IDs for a full regular season
28
+ and approximately 32 API calls (one per team).
25
29
 
26
30
  Args:
27
- season (str): Season to retrieve game IDs for in YYYYYYYY format (e.g., 20232024).
28
- game_types (List[int]): List of game types to include. Valid types:
29
- 1: Preseason
30
- 2: Regular season
31
- 3: Playoffs
32
- api_sleep_rate (float): Sleep rate in seconds between API calls to avoid hitting rate limits.
31
+ season (str): Season in YYYYYYYY format (e.g., "20232024").
32
+ game_types (List[int], optional): Game types to include. Valid values:
33
+
34
+ - ``1`` -- Preseason
35
+ - ``2`` -- Regular season
36
+ - ``3`` -- Playoffs
37
+
38
+ Defaults to ``None`` (all game types).
39
+ api_sleep_rate (float): Seconds to sleep between API calls to
40
+ avoid rate limiting. Defaults to ``1``.
33
41
 
34
42
  Returns:
35
- List of game IDs for the specified season and game types.
43
+ List[str]: Game IDs matching the requested season and game types.
44
+
45
+ Note:
46
+ This method makes one API call per team (~32 calls) and respects
47
+ ``api_sleep_rate`` between each call. Total runtime depends on the
48
+ sleep rate chosen.
36
49
  """
37
50
  from nhlpy.api.teams import Teams
38
51
  from nhlpy.api.schedule import Schedule
@@ -60,13 +73,30 @@ class Helpers:
60
73
  return game_ids
61
74
 
62
75
  def all_players(self, season: str, api_sleep_rate: float = 0.5) -> List[dict[str, Any]]:
63
- """Gets all player base stats.
76
+ """Gets every rostered player across all 32 NHL teams for a given season.
77
+
78
+ Iterates over every team roster and returns a flat list of player
79
+ dicts with cleaned name fields and an added ``team`` key. Makes
80
+ approximately 32 API calls (one per team).
64
81
 
65
82
  Args:
66
- api_sleep_rate (float): Sleep rate in seconds between API calls to avoid hitting rate limits.
83
+ season (str): Season in YYYYYYYY format (e.g., "20232024").
84
+ api_sleep_rate (float): Seconds to sleep between API calls to
85
+ avoid rate limiting. Defaults to ``0.5``.
67
86
 
68
87
  Returns:
69
- List of player base stats.
88
+ List[dict[str, Any]]: List of player dicts. Key fields include:
89
+
90
+ - ``id`` (int): Player ID.
91
+ - ``firstName`` (str): Cleaned first name (``default`` value).
92
+ - ``lastName`` (str): Cleaned last name (``default`` value).
93
+ - ``sweaterNumber`` (int): Jersey number.
94
+ - ``positionCode`` (str): Position code (e.g., "C", "D", "G").
95
+ - ``team`` (str): Team abbreviation added by this method.
96
+
97
+ Note:
98
+ This method makes one API call per team (~32 calls) and respects
99
+ ``api_sleep_rate`` between each call.
70
100
  """
71
101
  from nhlpy.api.teams import Teams
72
102
 
@@ -90,7 +120,28 @@ class Helpers:
90
120
  return out_data
91
121
 
92
122
  def all_players_summary_statistics(self, season: str, api_sleep_rate: float = 1):
93
- """Gets all player summary statistics for a specified season."""
123
+ """Gets summary statistics for every skater in a given season.
124
+
125
+ Combines roster data from ``all_players()`` with per-team summary
126
+ stats fetched through the query builder, then merges the two datasets
127
+ on player ID. Makes multiple paginated API calls (one roster call
128
+ per team plus one stats call per team franchise).
129
+
130
+ Args:
131
+ season (str): Season in YYYYYYYY format (e.g., "20232024").
132
+ api_sleep_rate (float): Seconds to sleep between API calls to
133
+ avoid rate limiting. Defaults to ``1``.
134
+
135
+ Returns:
136
+ list[dict]: Merged player and summary-stats dicts. Each entry
137
+ contains the roster fields from ``all_players()`` plus stats
138
+ fields such as ``goals``, ``assists``, ``points``,
139
+ ``gamesPlayed``, and other summary report columns.
140
+
141
+ Warning:
142
+ This method is slow and makes a large number of API calls.
143
+ Increase ``api_sleep_rate`` if you encounter rate limiting.
144
+ """
94
145
  logging.warning(
95
146
  "This method will take a while to run. In the event of rate limiting, you may need to increase the api_sleep_rate."
96
147
  )