Skip to content

Commit

Permalink
docs: convert docstrings to Google style format (#99)
Browse files Browse the repository at this point in the history
* docs: convert docstrings to Google style format

- Add parameter types and improve descriptions
- Standardize Returns sections
- Add Examples where relevant for API endpoints
- Maintain existing function implementations

change: page limits to 25 were applicable
  • Loading branch information
coreyjs authored Jan 9, 2025
1 parent 5dc7bdd commit 9e55b10
Show file tree
Hide file tree
Showing 12 changed files with 620 additions and 261 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ NHL-api-py is a Python package that provides a simple wrapper around the
NHL API, allowing you to easily access and retrieve NHL data in your Python
applications.

Note: This is ~~very early~~ maturing, I created this to help me with some machine learning
projects around the NHL and the NHL data sets. Special thanks to https://github.com/erunion/sport-api-specifications/tree/master/nhl, https://gitlab.com/dword4/nhlapi/-/blob/master/stats-api.md and https://github.com/Zmalski/NHL-API-Reference.

Note: I created this to help me with some machine learning
projects around the NHL and the NHL data sets. Special thanks to https://github.com/erunion/sport-api-specifications/tree/master/nhl,
https://gitlab.com/dword4/nhlapi/-/blob/master/stats-api.md and https://github.com/Zmalski/NHL-API-Reference.


### Developer Note: This is being updated with the new, also undocumented, NHL API.

Expand Down Expand Up @@ -235,7 +238,7 @@ query_context.errors

```python

client.stats.club_stats_season(team_abbr="BUF") # kinda weird endpoint.
client.stats.gametypes_per_season_directory_by_team(team_abbr="BUF") # kinda weird endpoint.

client.stats.player_career_stats(player_id="8478402")

Expand Down
88 changes: 54 additions & 34 deletions nhlpy/api/game_center.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,63 @@ def __init__(self, http_client: HttpClient):
self.client = http_client

def boxscore(self, game_id: str) -> dict:
"""
Get the boxscore for the game_id. GameIds can be retrieved from the schedule endpoint.
:param game_id: The game_id for the game you want the boxscore for.
"""Get boxscore data for a specific NHL game. GameIds can be retrieved from the schedule endpoint.
Args:
game_id (str): The game_id for the game you want the boxscore for
Example:
API endpoint format: https://api-web.nhle.com/v1/gamecenter/2023020280/boxscore
:example
https://api-web.nhle.com/v1/gamecenter/2023020280/boxscore
:return: dict
Returns:
dict: Game boxscore data
"""
return self.client.get(resource=f"gamecenter/{game_id}/boxscore").json()

def play_by_play(self, game_id: str) -> dict:
"""
Get the play by play for the game_id. GameIds can be retrieved from the schedule endpoint.
:param game_id: The game_id for the game you want the play by play for.
:return: dict
"""Get play-by-play data for a specific NHL game. GameIds can be retrieved from the schedule endpoint.
Args:
game_id (str): The game_id for the game you want the play by play for
Returns:
dict: Play-by-play game data
"""
return self.client.get(resource=f"gamecenter/{game_id}/play-by-play").json()

def landing(self, game_id: str) -> dict:
"""
Get verbose information about the matchup for the given game.
"""Get detailed match up information for a specific NHL game. GameIds can be retrieved
from the schedule endpoint.
Args:
game_id (str): The game_id for the game you want the landing page for
GameIds can be retrieved from the schedule endpoint.
:param game_id: The game_id for the game you want the landing page for.
:return: dict
Returns:
dict: Detailed game matchup data
"""
return self.client.get(resource=f"gamecenter/{game_id}/landing").json()

def score_now(self, date: Optional[str] = None) -> dict:
"""
Get the current score of all games in progress. I think, not totally sure.
Now param does not switch to new day until noon of that day.
:param date: Optional date, select date to see score. In format YYYY-MM-DD.
:return: dict
"""Get current scores for NHL games. GameDay updates at noon est I think.
Args:
date (str, optional): Date to check scores in YYYY-MM-DD format
Returns:
dict: Game scores and status information
"""
return self.client.get(resource=f"score/{date if date else 'now'}").json()

def shift_chart_data(self, game_id: str, excludes: List[str] = None) -> dict:
"""
Get shift chart data for the game_id. GameIds can be retrieved from the schedule endpoint.
:param excludes: List of strings of items to exclude from the response.
:param game_id: The game_id for the game you want the shift chart data for.
:return: dict
"""Gets shift chart data for a specific game.
Args:
game_id (str): ID of the game to retrieve shift data for. Game IDs can be retrieved
from the schedule endpoint.
excludes (List[str]): List of items to exclude from the response.
Returns:
Dict containing the shift chart data.
"""
if not excludes:
excludes = ["eventDetails"]
Expand All @@ -60,19 +74,25 @@ def shift_chart_data(self, game_id: str, excludes: List[str] = None) -> dict:
return self.client.get_by_url(full_resource=f"{base_url}?cayenneExp={expr_p}&exclude={exclude_p}").json()

def right_rail(self, game_id: str) -> dict:
"""
Get the game stats and season series information for the game_id.
GameIds can be retrieved from the schedule endpoint.
"""Gets game stats and season series information for a specific game.
:param game_id: The game_id for the game you want the stats for.
:return: dict
Args:
game_id (str): ID of the game to retrieve stats for. Game IDs can be retrieved
from the schedule endpoint.
Returns:
Dict containing game stats and season series data.
"""
return self.client.get(resource=f"gamecenter/{game_id}/right-rail").json()

def game_story(self, game_id: str) -> dict:
"""
Get game story information for the game id. GameIds can be retrieved from the schedule endpoint.
:param game_id: The game_id for the game you want the game story for.
:return: dict
"""Gets game story information for a specific game.
Args:
game_id (str): ID of the game to retrieve story for. Game IDs can be retrieved
from the schedule endpoint.
Returns:
Dict containing game story data.
"""
return self.client.get(resource=f"wsc/game-story/{game_id}").json()
15 changes: 11 additions & 4 deletions nhlpy/api/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@ def __init__(self, http_client: HttpClient) -> None:
self.client = http_client

def get_gameids_by_season(self, season: str, game_types: List[int] = None) -> List[str]:
"""
Get all gameids for a given season.
:param season: The season you want the gameids for. Format is YYYYYYYY. 20202021, 200232024, etc
:param game_types: List of game types you want to include. 2 is regular season, 3 is playoffs, 1 is preseason
"""Gets all game IDs for a specified season.
Args:
season (str): Season to retrieve game IDs for in YYYYYYYY format (e.g., 20232024).
game_types (List[int]): List of game types to include. Valid types:
1: Preseason
2: Regular season
3: Playoffs
Returns:
List of game IDs for the specified season and game types.
"""
from nhlpy.api.teams import Teams
from nhlpy.api.schedule import Schedule
Expand Down
35 changes: 20 additions & 15 deletions nhlpy/api/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,43 @@ def __init__(self, http_client: HttpClient) -> None:
self.client = http_client

def glossary(self) -> List[dict]:
"""
Get the glossary for the NHL API.
:return: dict
"""Get the glossary for the NHL API.
Returns:
dict: NHL API glossary data
"""
return self.client.get_by_url(full_resource="https://api.nhle.com/stats/rest/en/glossary?sort=fullName").json()[
"data"
]

def config(self) -> dict:
"""
Seems to be various options for the filters?.
:return: dict
"""Get available filter options.
Returns:
dict: Dictionary of filter options
"""
return self.client.get_by_url(full_resource="https://api.nhle.com/stats/rest/en/config").json()

def countries(self) -> List[dict]:
"""
Get the countries for the NHL API.
:return: dict
"""Get list of countries from NHL API.
Returns:
dict: Dictionary of country data
"""
return self.client.get_by_url(full_resource="https://api.nhle.com/stats/rest/en/country").json()["data"]

def season_specific_rules_and_info(self) -> List[dict]:
"""
Get the season specific rules and info for the NHL API.
:return: dict
"""Get NHL season rules and information.
Returns:
dict: Dictionary containing season-specific rules and information
"""
return self.client.get_by_url(full_resource="https://api.nhle.com/stats/rest/en/season").json()["data"]

def draft_year_and_rounds(self) -> List[dict]:
"""
Get the draft year and rounds for the NHL API. This only has "id", "draftYear" and "rounds count".
:return: dict
"""Get NHL draft year and round information.
Returns:
dict: Draft data containing 'id', 'draftYear', and 'rounds count'
"""
return self.client.get_by_url(full_resource="https://api.nhle.com/stats/rest/en/draft").json()["data"]
41 changes: 22 additions & 19 deletions nhlpy/api/playoffs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,46 @@ def __init__(self, http_client: HttpClient):
self.client = http_client

def carousel(self, season: str) -> dict:
"""
Get the list of all series games up to the current round.
"""Gets list of all series games up to current playoff round.
:param season: the current season ex. "20232024"
Args:
season (str): Season in YYYYYYYY format (e.g., "20232024")
example:
https://api-web.nhle.com/v1/playoff-series/carousel/20232024/
Returns:
dict: Playoff series data for the specified season.
:return: dict
Example:
API endpoint: https://api-web.nhle.com/v1/playoff-series/carousel/20232024/
"""
return self.client.get(resource=f"playoff-series/carousel/{season}").json()

def schedule(self, season: str, series: str) -> dict:
"""
Returns the schedule for a specified series.
"""Returns the schedule for a specified playoff series.
:param season: the season you wish to see the schedule of
:param series: the series (a-h) for Round 1
Args:
season (str): Season in YYYYYYYY format (e.g., "20232024")
series (str): Series identifier (a-h) for Round 1
example:
https://api-web.nhle.com/v1/schedule/playoff-series/20232024/a/
Returns:
dict: Schedule data for the specified playoff series.
:return: dict
Example:
API endpoint: https://api-web.nhle.com/v1/schedule/playoff-series/20232024/a/
"""

return self.client.get(resource=f"schedule/playoff-series/{season}/{series}").json()

def bracket(self, year: str) -> dict:
"""
Returns the playoff bracket
"""Returns the playoff bracket.
:param year: the year the playoffs are taking place ex. "2024"
Args:
year (str): Year playoffs take place (e.g., "2024")
example:
https://api-web.nhle.com/v1/playoff-bracket/2024
Returns:
dict: Playoff bracket data.
:return: dict
Example:
API endpoint: https://api-web.nhle.com/v1/playoff-bracket/2024
"""

return self.client.get(resource=f"playoff-bracket/{year}").json()
45 changes: 45 additions & 0 deletions nhlpy/api/query/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,68 @@


class QueryContext:
"""A container for query information and validation state.
This class holds the constructed query string, original filters, any validation
errors, and a base fact query. It provides methods to check query validity.
Attributes:
query_str (str): The constructed query string from all valid filters
filters (List[QueryBase]): List of original query filter objects
errors (List[str]): List of validation error messages
fact_query (str): Base fact query, defaults to "gamesPlayed>=1"
"""

def __init__(self, query: str, filters: List[QueryBase], fact_query: str = None, errors: List[str] = None):
self.query_str = query
self.filters = filters
self.errors = errors
self.fact_query = fact_query if fact_query else "gamesPlayed>=1"

def is_valid(self) -> bool:
"""Check if the query context is valid.
Returns:
bool: True if there are no validation errors, False otherwise
"""
return len(self.errors) == 0


class QueryBuilder:
"""Builds and validates query strings from a list of query filters.
This class processes a list of QueryBase filters, validates them, and combines
them into a single query string. It handles validation errors and provides
optional verbose logging.
Attributes:
_verbose (bool): When True, enables detailed logging of the build process
"""

def __init__(self, verbose: bool = False):
self._verbose = verbose
if self._verbose:
logging.basicConfig(level=logging.INFO)

def build(self, filters: List[QueryBase]) -> QueryContext:
"""Build a query string from a list of filters.
Processes each filter in the list, validates it, and combines valid filters
into a single query string using 'and' as the connector.
Args:
filters (List[QueryBase]): List of query filter objects to process
Returns:
QueryContext: A context object containing the query string, original filters,
and any validation errors
Notes:
- Skips filters that aren't instances of QueryBase
- Collects validation errors but continues processing remaining filters
- Combines valid filters with 'and' operator
- Returns empty query string if no valid filters are found
"""
result_query: str = ""
output_filters: List[str] = []
errors: List[str] = []
Expand Down
Loading

0 comments on commit 9e55b10

Please sign in to comment.