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-sdk

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.1.tar.gz (110.9 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.1-py3-none-any.whl (234.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: nhl_sdk-0.1.1.tar.gz
  • Upload date:
  • Size: 110.9 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.1.tar.gz
Algorithm Hash digest
SHA256 cf47959d7a62c39f009a0e68a45af0e7dc1a68d8192bbd17c257785012a13067
MD5 1f4d1d20053bda35ef4a1bfc014e8f8a
BLAKE2b-256 327de830e5d7242a2f5dcc757c3b9645b819dc4061b9afc72c8d260509e00389

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nhl_sdk-0.1.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 fe050775dcc64d54a2f8892f2dd2213f50d16505532107490065b17590c43b01
MD5 685a0f3b2e50cb2772294dd2c55666e9
BLAKE2b-256 d37774260b7d3e24fc24139d48179c927c18809153e941c8f2b03e2dea7b1387

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