|
11 | 11 | - [Teams](#teams) |
12 | 12 | - [Schedule](#schedule) |
13 | 13 | - [Stats](#stats) |
| 14 | + - [Edge Data](#edge) |
14 | 15 | - [Standings](#standings) |
15 | 16 | - [Game Center](#game-center) |
16 | 17 | - [Misc](#misc) |
@@ -97,6 +98,7 @@ They are grouped by function to make the library easier to navigate and use. Th |
97 | 98 | - **`teams`**: Contains endpoints related to NHL teams, including team information and rosters. You can find team_id(s) here along with franchise_id(s) needed for some of the stats queries. |
98 | 99 | - **`schedule`**: Contains endpoints related to the NHL schedule, including game dates, weekly schedules, and team schedules. |
99 | 100 | - **`stats`**: Contains endpoints related to player and team statistics. This will have your basic stats, summary stats and more advanced stats using the new query builder, which allows for more complex queries to be built up programmatically. |
| 101 | +- **`edge`**: Contains endpoints to access EDGE related player and team data (shot speed, skate speed, etc). These were well hidden endpoints from the NHL and behave a bit differently with their response payloads. |
100 | 102 | - **`standings`**: Contains endpoints related to NHL standings, including current standings and historical standings. |
101 | 103 | - **`game_center`**: Contains endpoints related to game center data, including box scores, play-by-play data, and game summaries. |
102 | 104 | - **`misc`**: Contains miscellaneous endpoints that don't fit into the other categories, such as glossary terms, configuration data, and country information. |
@@ -155,24 +157,6 @@ print(f"Defensemen: {len(roster['defensemen'])}") |
155 | 157 | print(f"Goalies: {len(roster['goalies'])}") |
156 | 158 | ``` |
157 | 159 |
|
158 | | -<details> |
159 | | -<summary>📋 Full Response Examples</summary> |
160 | | - |
161 | | -**teams() response:** |
162 | | -```json |
163 | | - |
164 | | -``` |
165 | | - |
166 | | -**team_roster() response:** |
167 | | -```json |
168 | | - |
169 | | -``` |
170 | | - |
171 | | -**franchises() response:** |
172 | | -```json |
173 | | - |
174 | | -``` |
175 | | -</details> |
176 | 160 |
|
177 | 161 | # Schedule |
178 | 162 |
|
@@ -256,11 +240,64 @@ for game in games.get('games', []): |
256 | 240 | ``` |
257 | 241 |
|
258 | 242 | <details> |
259 | | -<summary>📋 Full Response Examples</summary> |
| 243 | +<summary>Response Examples</summary> |
260 | 244 |
|
261 | 245 | **daily_schedule() response:** |
262 | 246 | ```json |
263 | 247 |
|
| 248 | + 'date': '2024-10-08', |
| 249 | + 'games': [ |
| 250 | + { |
| 251 | + 'awayTeam': { |
| 252 | + 'abbrev': 'STL', |
| 253 | + 'awaySplitSquad': False, |
| 254 | + 'commonName': { |
| 255 | + 'default': 'Blues' |
| 256 | + }, |
| 257 | + 'darkLogo': 'https://assets.nhle.com/logos/nhl/svg/STL_20082009-20242025_dark.svg', |
| 258 | + 'id': 19, |
| 259 | + 'logo': 'https://assets.nhle.com/logos/nhl/svg/STL_20082009-20242025_light.svg', |
| 260 | + 'placeName': { |
| 261 | + 'default': 'St. Louis' |
| 262 | + }, |
| 263 | + 'placeNameWithPreposition': { |
| 264 | + 'default': 'St. Louis', |
| 265 | + 'fr': 'de St. Louis' |
| 266 | + }, |
| 267 | + 'score': 3 |
| 268 | + }, |
| 269 | + 'easternUTCOffset': '-04:00', |
| 270 | + 'gameCenterLink': '/gamecenter/stl-vs-sea/2024/10/08/2024020003', |
| 271 | + 'gameOutcome': { |
| 272 | + 'lastPeriodType': 'REG' |
| 273 | + }, |
| 274 | + 'gameScheduleState': 'OK', |
| 275 | + 'gameState': 'OFF', |
| 276 | + 'gameType': 2, |
| 277 | + 'homeTeam': { |
| 278 | + 'abbrev': 'SEA', |
| 279 | + 'commonName': { |
| 280 | + 'default': 'Kraken' |
| 281 | + }, |
| 282 | + 'darkLogo': 'https://assets.nhle.com/logos/nhl/svg/SEA_dark.svg', |
| 283 | + 'homeSplitSquad': False, |
| 284 | + 'id': 55, |
| 285 | + 'logo': 'https://assets.nhle.com/logos/nhl/svg/SEA_light.svg', |
| 286 | + 'placeName': { |
| 287 | + 'default': 'Seattle' |
| 288 | + }, |
| 289 | + 'placeNameWithPreposition': { |
| 290 | + 'default': 'Seattle', |
| 291 | + 'fr': 'de Seattle' |
| 292 | + }, |
| 293 | + 'score': 2 |
| 294 | + }, |
| 295 | + ..... |
| 296 | + }] |
| 297 | + |
| 298 | +STL @ SEA - 2024-10-08T20:30:00Z |
| 299 | +BOS @ FLA - 2024-10-08T23:00:00Z |
| 300 | +CHI @ UTA - 2024-10-09T02:00:00Z |
264 | 301 | ``` |
265 | 302 | </details> |
266 | 303 |
|
@@ -347,21 +384,143 @@ stats = client.stats.skater_stats_summary( |
347 | 384 | # Show top 5 scorers |
348 | 385 | for i, player in enumerate(stats[:5]): |
349 | 386 | print(f"{i+1}. {player['skaterFullName']}: {player['points']} points") |
| 387 | + |
| 388 | +1. Nikita Kucherov: 121 points |
| 389 | +2. Nathan MacKinnon: 116 points |
| 390 | +3. Leon Draisaitl: 106 points |
| 391 | +4. David Pastrnak: 106 points |
| 392 | +5. Mitch Marner: 102 points |
350 | 393 | ``` |
351 | 394 |
|
352 | | -<details> |
353 | | -<summary>📋 Full Response Examples</summary> |
| 395 | +# Edge |
354 | 396 |
|
355 | | -**player_career_stats() response:** |
356 | | -```json |
| 397 | +Get EDGE related player and team data. (Note, these endpoints were well hidden and behave |
| 398 | +a bit differently. Their payloads are less verbose than the others.) |
| 399 | + |
| 400 | +It should be noted that these endpoints may be unstable and change often resulting in |
| 401 | +failed requests. These seem to be for internal use for the NHL edge graphics, so data is often structured strangely. |
| 402 | + |
| 403 | +```python |
| 404 | +client.edge.skater_detail(player_id='8478402', season='20252026') |
| 405 | + |
| 406 | +client.edge.skater_shot_speed_detail(player_id='8478402', season='20252026') |
| 407 | + |
| 408 | +client.edge.skater_skating_speed_detail(player_id='8478402', season='20252026') |
357 | 409 |
|
| 410 | +client.edge.skater_shot_location_detail(player_id='8478402', season='20252026') |
| 411 | + |
| 412 | +client.edge.skater_skating_distance_detail(player_id='8478402', season='20252026') |
| 413 | + |
| 414 | +client.edge.skater_comparison(player_id='8478402', season='20252026') |
| 415 | + |
| 416 | +client.edge.skater_zone_time(player_id='8478402', season='20252026') |
| 417 | + |
| 418 | +client.edge.skater_landing(season='20252026') |
| 419 | + |
| 420 | +client.edge.cat_skater_detail(player_id='8478402', season='20252026') |
| 421 | + |
| 422 | +client.edge.goalie_detail(player_id='8478402', season='20252026') |
| 423 | + |
| 424 | +client.edge.goalie_shot_location_detail(player_id='8478402', season='20252026') |
| 425 | + |
| 426 | +client.edge.goalie_5v5_detail(player_id='8478402', season='20252026') |
| 427 | + |
| 428 | +client.edge.goalie_comparison(player_id='8478402', season='20252026') |
| 429 | + |
| 430 | +client.edge.goalie_save_percentage_detail(player_id='8478402', season='20252026') |
| 431 | + |
| 432 | +client.edge.goalie_landing(season='20252026') |
| 433 | + |
| 434 | +client.edge.cat_goalie_detail(player_id='8478402', season='20252026') |
| 435 | + |
| 436 | +client.edge.team_detail(team_id='19', season='20252026') |
| 437 | + |
| 438 | +client.edge.team_skating_distance_detail(team_id='19', season='20252026') |
| 439 | + |
| 440 | +client.edge.team_zone_time_details(team_id='19', season='20252026') |
| 441 | + |
| 442 | +client.edge.team_shot_location_detail(team_id='19', season='20252026') |
| 443 | + |
| 444 | +client.edge.team_landing(team_id='19', season='20252026') |
| 445 | + |
| 446 | +client.edge.team_shot_speed_detail(team_id='19', season='20252026') |
| 447 | + |
| 448 | +client.edge.team_skating_speed_detail(team_id='19', season='20252026') |
358 | 449 | ``` |
359 | 450 |
|
360 | | -**skater_stats_summary_simple() response:** |
361 | | -```json |
| 451 | +## Skater Detail |
| 452 | + |
| 453 | +```python |
| 454 | +detail = client.edge.skater_detail(player_id='8478402', season="20252026") |
362 | 455 |
|
| 456 | +... |
| 457 | +'skatingSpeed': { |
| 458 | + 'burstsOver20': { |
| 459 | + 'leagueAvg': { |
| 460 | + 'value': 13.9179 |
| 461 | + }, |
| 462 | + 'percentile': 1.0, |
| 463 | + 'value': 91 |
| 464 | + }, |
| 465 | + 'speedMax': { |
| 466 | + 'imperial': 24.612, |
| 467 | + 'leagueAvg': { |
| 468 | + 'imperial': 21.7285, |
| 469 | + 'metric': 34.9685 |
| 470 | + }, |
| 471 | + 'metric': 39.609, |
| 472 | + 'overlay': { |
| 473 | + 'awayTeam': { |
| 474 | + 'abbrev': 'CGY', |
| 475 | + 'score': 4 |
| 476 | + }, |
| 477 | + 'gameDate': '2025-10-08', |
| 478 | + 'gameOutcome': { |
| 479 | + 'lastPeriodType': 'SO' |
| 480 | + }, |
| 481 | + 'gameType': 2, |
| 482 | + 'homeTeam': { |
| 483 | + 'abbrev': 'EDM', |
| 484 | + 'score': 3 |
| 485 | + }, |
| 486 | + 'periodDescriptor': { |
| 487 | + 'maxRegulationPeriods': 3, |
| 488 | + 'number': 2, |
| 489 | + 'periodType': 'REG' |
| 490 | + }, |
| 491 | + 'player': { |
| 492 | + 'firstName': { |
| 493 | + 'default': 'Connor' |
| 494 | + }, |
| 495 | + 'lastName': { |
| 496 | + 'default': 'McDavid' |
| 497 | + } |
| 498 | + }, |
| 499 | + 'timeInPeriod': '08:04' |
| 500 | + }, |
| 501 | + 'percentile': 1.0 |
| 502 | +... |
363 | 503 | ``` |
364 | | -</details> |
| 504 | + |
| 505 | +[Example Response](https://github.com/coreyjs/nhl-api-py/wiki/edge.skater_detail) |
| 506 | + |
| 507 | + |
| 508 | +## Skater Shot Speed Details |
| 509 | + |
| 510 | +```python |
| 511 | +detail = client.edge.skater_shot_speed_detail(player_id='8478402', season="20252026") |
| 512 | +``` |
| 513 | + |
| 514 | +[Example Response](https://github.com/coreyjs/nhl-api-py/wiki/edge.skater_shot_speed_detail) |
| 515 | + |
| 516 | + |
| 517 | +## Skater Skating Speed Detail |
| 518 | + |
| 519 | +```python |
| 520 | +detail = client.edge.skater_skating_speed_detail(player_id='8478402', season='20252026') |
| 521 | +``` |
| 522 | + |
| 523 | +--- |
365 | 524 |
|
366 | 525 | # Standings |
367 | 526 |
|
@@ -411,14 +570,6 @@ for division, team in divisions.items(): |
411 | 570 | print(f"{division}: {team['teamName']['default']} ({team['points']} pts)") |
412 | 571 | ``` |
413 | 572 |
|
414 | | -<details> |
415 | | -<summary>📋 Full Response Examples</summary> |
416 | | - |
417 | | -**league_standings() response:** |
418 | | -```json |
419 | | - |
420 | | -``` |
421 | | -</details> |
422 | 573 |
|
423 | 574 | # Game Center |
424 | 575 |
|
@@ -495,19 +646,6 @@ for period, shots in shots_by_period.items(): |
495 | 646 | print(f"Period {period}: {shots} shots") |
496 | 647 | ``` |
497 | 648 |
|
498 | | -<details> |
499 | | -<summary>📋 Full Response Examples</summary> |
500 | | - |
501 | | -**boxscore() response:** |
502 | | -```json |
503 | | - |
504 | | -``` |
505 | | - |
506 | | -**play_by_play() response:** |
507 | | -```json |
508 | | - |
509 | | -``` |
510 | | -</details> |
511 | 649 |
|
512 | 650 | # Misc |
513 | 651 |
|
@@ -561,20 +699,6 @@ for term in stat_terms: |
561 | 699 | continue |
562 | 700 | ``` |
563 | 701 |
|
564 | | -<details> |
565 | | -<summary>📋 Full Response Examples</summary> |
566 | | - |
567 | | -**glossary() response:** |
568 | | -```json |
569 | | - |
570 | | -``` |
571 | | - |
572 | | -**countries() response:** |
573 | | -```json |
574 | | - |
575 | | -``` |
576 | | -</details> |
577 | | - |
578 | 702 | --- |
579 | 703 | # Advanced Usage |
580 | 704 |
|
@@ -734,7 +858,6 @@ This should support the following filters: |
734 | 858 | - `shots` |
735 | 859 |
|
736 | 860 | ```python |
737 | | -..... |
738 | 861 | query_builder = QueryBuilder() |
739 | 862 | query_context: QueryContext = query_builder.build(filters=filters) |
740 | 863 |
|
|
0 commit comments