Skip to main content

unofficial SDK for the NHL API

Project description

NHL Stats SDK

PyPI version

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_sdk
pip install -e .

Quick Start

from nhl_sdk.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_sdk.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_sdk.core.config import DefaultConfig
from nhl_sdk.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_sdk.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_sdk.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.2.tar.gz (114.5 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.2-py3-none-any.whl (233.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: nhl_sdk-0.1.2.tar.gz
  • Upload date:
  • Size: 114.5 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.2.tar.gz
Algorithm Hash digest
SHA256 29ada1994bc4f07d9b926912a3dc587bc3cbc1c4241f1b68c16dc419b9749578
MD5 a92210c956050c7f8a8944fd4293e1cc
BLAKE2b-256 8d519ffc5c7517c15d0c6ffd9af9c9ab5fb57624218b4d95c1c03bd9bf2a8974

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nhl_sdk-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 233.0 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f40fcb1346a36cb4032ac699542f7d0ffe47b5ae42cd9b907379aa279d97c277
MD5 12d74227ca60de260228820d845b3bde
BLAKE2b-256 a6a4e866bbcea78efdd3e73a408faa93e9cd64ba2dd7c6f5282fe9279d6841dd

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