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.
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/PKG-INFO +1 -1
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/edge.py +195 -0
- nhl_api_py-3.3.0/nhlpy/api/game_center.py +214 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/helpers.py +63 -12
- nhl_api_py-3.3.0/nhlpy/api/misc.py +108 -0
- nhl_api_py-3.3.0/nhlpy/api/players.py +68 -0
- nhl_api_py-3.3.0/nhlpy/api/schedule.py +302 -0
- nhl_api_py-3.3.0/nhlpy/api/standings.py +94 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/stats.py +100 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/teams.py +71 -19
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/pyproject.toml +1 -1
- nhl_api_py-3.2.3/nhlpy/api/game_center.py +0 -100
- nhl_api_py-3.2.3/nhlpy/api/misc.py +0 -52
- nhl_api_py-3.2.3/nhlpy/api/players.py +0 -35
- nhl_api_py-3.2.3/nhlpy/api/schedule.py +0 -164
- nhl_api_py-3.2.3/nhlpy/api/standings.py +0 -65
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/LICENSE +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/README.md +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/__init__.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/__init__.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/__init__.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/builder.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/__init__.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/decision.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/draft.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/experience.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/franchise.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/game_type.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/home_road.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/nationality.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/opponent.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/position.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/season.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/shoot_catch.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/filters/status.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/sorting/__init__.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/api/query/sorting/sorting_options.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/config.py +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/data/seasonal_information_manifest.json +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/data/team_stat_ids.json +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/data/teams_20232024.json +0 -0
- {nhl_api_py-3.2.3 → nhl_api_py-3.3.0}/nhlpy/http_client.py +0 -0
- {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.
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
)
|