Skip to main content

unofficial SDK for the NHL API

Project description

NHL Stats SDK

An unofficial Python SDK for the NHL API. Personal side project built for fun — no guarantees on cadence, but actively maintained.

Only possible due to the great work by Zmalski documenting the NHL API. Full Postman collection for manual testing available here.


Requirements

  • Python 3.13+

Installation

pip install nhl-stats

Or clone the repo and install in editable mode for local development:

git clone https://github.com/PandaBacon21/nhl-sdk.git
cd nhl-sdk/nhl_stats
pip install -e .

Quick Start

from nhl_stats.client import NhlClient

client = NhlClient()

# --- Players ---
player = client.players.get(8477492)   # Nathan MacKinnon — gateway object, player ID baked in

print(player.profile.first_name)       # biographical info
print(player.stats.career)             # career totals from landing
pp  = player.stats.powerplay()         # one of 20+ named api_stats reports (season, game_type optional)
log = player.stats.game_log(season=20242025, game_type=2)

print(player.achievements.awards)      # awards, badges, HHOF status, top-100
milestones = player.achievements.milestones()

# Collection-level — spotlight, stat leaders, league-wide milestones
spotlight  = client.players.spotlight
leaders    = client.players.leaders
milestones = client.players.milestones(milestone="Goals", position="s")  # skaters only

# --- Teams ---
team = client.teams.get("COL")         # Team gateway — abbreviation and team ID baked in

stats    = team.stats.get_team_stats()
summary  = team.stats.get_summary()    # api_stats aggregate (PP%, PK%, goals for/against, etc.)
roster   = team.roster.get_team_roster()
schedule = team.schedule.get_schedule()

standings = client.teams.standings.get_standings()

# --- League ---
schedule       = client.league.get_schedule(date="2025-01-15")
seasons        = client.league.get_seasons()
season_details = client.league.get_season_details()

# --- Games ---
game    = client.games.get(2024020001)  # Game gateway — game ID baked in
pbp     = game.pbp()
landing = game.landing()
shifts  = game.shifts()

scores     = client.games.scores.get_daily_scores(date="2025-01-15")
scoreboard = client.games.scoreboard.get_scoreboard()

# --- Draft ---
rankings = client.draft.rankings.get_rankings()
picks    = client.draft.picks.get_all(year=2024)
tracker  = client.draft.tracker.get_tracker_now()

# --- Playoffs ---
carousel = client.playoffs.carousel.get_carousel(season=20242025)
bracket  = client.playoffs.bracket.get_bracket(year=2024)

# --- Misc ---
meta      = client.misc.meta()
location  = client.misc.location()
countries = client.misc.countries
ping      = client.misc.ping()

# --- NHL Edge ---
# Player edge — returns SkaterEdge or GoalieEdge based on position
edge  = player.stats.edge()
speed = edge.skating_speed()

# Team edge — per-team detail
distance = team.stats.edge.skating_distance.get_skating_distance()

# Team edge — league-wide leaderboards
dist_top = client.teams.edge.skating_distance_top_10.get_top_10()

What's Included

Namespace What it covers
client.players Player gateway (profile, stats, achievements), stat leaders, spotlight, league-wide milestones, player list query
client.teams Team gateway (stats, roster, schedule), standings, all-teams reference list
client.league League schedule, schedule calendar, season list, season details, component season
client.games Game gateway (pbp, landing, boxscore, story, shifts), daily scores, scoreboard, TV schedule, odds, streams
client.draft Prospect rankings, live draft tracker, picks, all-picks, draft query
client.playoffs Series carousel, per-series schedule, full bracket
client.misc Location, postal lookup, meta, game rail, replays, WSC play-by-play, reference data (countries, franchises, glossary, config)

Player statsPlayer.stats exposes career totals, season splits, and game logs from the landing endpoint, plus 20 named per-player reports sourced from the NHL Stats API (summary, bio, faceoff, penalties, TOI, power play, penalty kill, realtime, and more). NHL Edge per-player data is available via Player.stats.edge().

Team statsTeamStats covers per-player skater/goalie stats, aggregate team summaries (PP%, PK%, goals for/against), and team reference data. NHL Edge per-team detail is via TeamEdge and league-wide leaderboards via TeamsEdge.


Configuration

NhlClient accepts optional keyword arguments. All fields have defaults and can be overridden individually or via a BaseConfig object.

from nhl_stats.client import NhlClient

client = NhlClient(
    log_name="my_app",        # logger name              (default: "nhl_sdk")
    log_level="INFO",         # DEBUG|INFO|WARNING|ERROR  (default: "WARNING")
    log_file="/tmp/nhl.log",  # log file path; None = stdout only (default: None)
    lang="en",                # response language         (default: "en")
    cache=my_cache,           # custom BaseCache impl     (default: MemCache)
)

By default, logs are written to stdout only (log_file=None). Pass any file path string to write to a file instead.

Custom Config Object

from nhl_stats.core.config import DefaultConfig
from nhl_stats.client import NhlClient

config = DefaultConfig(log_level="WARNING", log_file=None)
client = NhlClient(config_from_object=config)

Custom Cache

Implement BaseCache to plug in any backend (Redis, file-based, etc.):

from nhl_stats.core.cache.base_cache import BaseCache

class MyCache(BaseCache):
    def get(self, key): ...
    def set(self, key, data, ttl): ...
    def delete(self, key): ...
    def clear(self): ...

API Reference

Full method and property documentation is in docs/api-reference.md.


Error Handling

The NHL API is public and requires no authentication. As this is an unofficial SDK against an undocumented API, there is no guarantee that endpoints or response structures won't change, and unexpected errors outside those listed below may occur.

On HTTP 429, the SDK automatically retries up to 3 times with exponential backoff. The Retry-After response header is respected when present, capped at 60s with a minimum of 1s per retry. RateLimitError is raised only after all retries are exhausted. In practice, the NHL API returns Retry-After: 60 on rate limit and counts it down across successive 429 responses in the same window.

from nhl_stats.core.errors import NotFoundError, RateLimitError, NhlApiError

try:
    player = client.players.get(9999999)
    _ = player.profile
except NotFoundError as e:
    print(f"Player not found: {e} (status {e.status_code})")
except RateLimitError:
    print("Rate limited — retries exhausted")
except NhlApiError as e:
    print(f"API error: {e}")
Exception HTTP Status
NotFoundError 404
RateLimitError 429
ServerError 5xx
NhlApiError Base class / other

License

MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nhl_sdk-0.1.0.tar.gz (110.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nhl_sdk-0.1.0-py3-none-any.whl (234.1 kB view details)

Uploaded Python 3

File details

Details for the file nhl_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: nhl_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 110.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for nhl_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6dcf07e4092f0aee353c514566a1979c6e3fb7dace3dbf9ccd79d15879321762
MD5 e920dd396f1a6141c42a8e6a5eacf1fd
BLAKE2b-256 479f0010181b922a05bb76c3c6c3b63d99616d2cb6938f05935cf86b6dae7911

See more details on using hashes here.

File details

Details for the file nhl_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: nhl_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 234.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for nhl_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8925b5af7410d078047bc383c61cc0041b1e11381444dbf33895d047a5b8d81e
MD5 661db0b78b553ad6960d4a8a9a56b8a1
BLAKE2b-256 555b1d9081d6c87df5e842dae28a15ee9a7b10adb109229c61bcabc2e2ca9922

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page