### Install fastbreak Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Installs the fastbreak Python package from PyPI. Requires Python 3.12 or later. ```bash pip install fastbreak ``` -------------------------------- ### Async Context Manager for NBAClient Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Demonstrates the correct usage of the `async with` statement with `NBAClient` to ensure the underlying `aiohttp.ClientSession` is properly managed and closed, preventing resource warnings. ```python async with NBAClient() as client: # session is created lazily on first request result = await client.get(...) # session is closed here, even if an exception was raised above ``` -------------------------------- ### Bring Your Own Structlog Configuration (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Illustrates how Fastbreak respects an existing structlog configuration. If `structlog.configure()` is called before importing `fastbreak`, Fastbreak will not override the logger setup. ```python import structlog # Configure structlog your way first structlog.configure(...) # Now import fastbreak, it will use the existing configuration ``` -------------------------------- ### Embedding fastbreak in a web server Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Shows how to instantiate `NBAClient` with `handle_signals=False` when embedding it within an application that manages its own event loop, like a FastAPI or aiohttp server. Manual closing of the client is then required if not using the async context manager. ```python client = NBAClient(handle_signals=False) # ... later, when shutting down ... # await client.close() ``` -------------------------------- ### Import NBAClient from fastbreak.clients Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Demonstrates how to import the NBAClient class from the fastbreak.clients module. This client is used to interact with the NBA statistics API. ```python from fastbreak.clients import NBAClient ``` -------------------------------- ### Running async fastbreak code in a script Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Illustrates the standard pattern for running asynchronous fastbreak operations within a Python script using `asyncio.run()` to manage the event loop and execute a `main()` coroutine. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.endpoints import LeagueStandings async def main(): async with NBAClient() as client: standings = await client.get(LeagueStandings(season="2025-26")) print(standings.standings[0].team_name) asyncio.run(main()) ``` -------------------------------- ### Install fastbreak with DataFrame dependencies Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Installs fastbreak with optional dependencies for pandas and/or polars DataFrame support. You only need to install what you use. ```bash pip install fastbreak pandas ``` ```bash pip install fastbreak polars ``` ```bash pip install fastbreak pandas polars ``` -------------------------------- ### Search and Get Player Profile (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/players.md Provides an example of searching for players by name and retrieving a detailed profile for a specific player. It demonstrates using `search_players` for partial matches and `get_player` for exact lookups, then displaying key profile information. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.players import get_player, search_players async def main(): async with NBAClient() as client: # Search by partial name results = await search_players(client, "ant") print(f"Found {len(results)} matches for 'ant':") for p in results: team = p.team_abbreviation or "FA" print(f" {p.person_id} {p.player_first_name} {p.player_last_name} ({team})") print() # Exact lookup player = await get_player(client, "Anthony Edwards") if player: print(f"Anthony Edwards profile:") print(f" ID: {player.person_id}") print(f" Team: {player.team_city} {player.team_name} ({player.team_abbreviation})") print(f" Position: {player.position}") print(f" Height: {player.height}") print(f" College: {player.college}") if player.pts is not None: print(f" Stats: {player.pts:.1f} pts / {player.reb:.1f} reb / {player.ast:.1f} ast") asyncio.run(main()) ``` -------------------------------- ### Basic Single Request Example Source: https://github.com/reidhoch/fastbreak/blob/main/docs/endpoints.md Example of making a basic single request to the PlayerGameLog endpoint using the NBAClient. ```APIDOC ## Basic Single Request ### Description This example demonstrates how to fetch a player's game log for a specific season. ### Method GET ### Endpoint /stats/playergamelog ### Parameters #### Query Parameters - **player_id** (integer) - Required - The ID of the player (e.g., 2544 for LeBron James). - **season** (string) - Required - The season in 'YYYY-YY' format (e.g., '2024-25'). - **season_type** (string) - Required - The type of season (e.g., 'Regular Season'). ### Request Example ```python from fastbreak.clients import NBAClient from fastbreak.endpoints import PlayerGameLog async with NBAClient() as client: log = await client.get( PlayerGameLog( player_id=2544, # LeBron James season="2024-25", season_type="Regular Season", ) ) for game in log.games: print(f"{game.game_date}: {game.pts} pts, {game.reb} reb, {game.ast} ast") ``` ### Response #### Success Response (200) - **PlayerGameLogResponse** (object) - Contains the game log data for the player. ``` -------------------------------- ### Configure Default Retries in Python Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Demonstrates the default retry behavior of the NBAClient with up to 3 retry attempts and exponential backoff between 1 and 10 seconds. This configuration is applied automatically if not explicitly set. ```python async with NBAClient( max_retries=3, retry_wait_min=1.0, retry_wait_max=10.0, ) as client: result = await client.get(...) ``` -------------------------------- ### Install Development Dependencies with uv Source: https://github.com/reidhoch/fastbreak/blob/main/CONTRIBUTING.md Installs the development dependencies for the fastbreak project using the 'uv' package manager. Ensures all necessary tools for development are available. ```bash uv sync --group dev ``` -------------------------------- ### Set Logging Environment Variables in Python Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Shows how to set the `FASTBREAK_LOG_LEVEL` and `FASTBREAK_LOG_FORMAT` environment variables programmatically within a Python script before importing the `fastbreak` library. This ensures Fastbreak configures structlog as desired. ```python import os os.environ["FASTBREAK_LOG_LEVEL"] = "DEBUG" os.environ["FASTBREAK_LOG_FORMAT"] = "json" import fastbreak # logging configured here ``` -------------------------------- ### Install fastbreak dependencies Source: https://github.com/reidhoch/fastbreak/blob/main/README.md Commands to install the fastbreak package via pip, with optional support for pandas or polars dataframes. ```bash pip install fastbreak pip install fastbreak pandas # or polars ``` -------------------------------- ### Example: Using stat_delta for Comparisons Source: https://github.com/reidhoch/fastbreak/blob/main/docs/splits.md Provides examples of using the `stat_delta` function to compare statistics. It shows how to calculate the difference in field goal percentage between home and road games and demonstrates its `None`-safe behavior when one of the values is missing. ```python from fastbreak.splits import stat_delta # Assuming 'home' and 'road' are objects with 'fg_pct' attribute # and 'last_5' is an object with 'pts' attribute # Home vs road FG% edge # stat_delta(home.fg_pct, road.fg_pct) # e.g., 0.027 (home 2.7pp better) # None-safe: returns None if data is missing for either window # stat_delta(last_5.pts, None) # → None ``` -------------------------------- ### Fastbreak Season Utilities Examples (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/seasons.md This Python code snippet provides runnable examples for key functions in the fastbreak.seasons module: `get_season_from_date`, `season_start_year`, and `season_to_season_id`. It illustrates how these functions handle different date inputs and convert season strings to IDs. ```python from datetime import date from fastbreak.seasons import ( get_season_from_date, season_start_year, season_to_season_id, ) # get_season_from_date print(get_season_from_date()) # "2025-26" (today: 2026-02-27) print(get_season_from_date(date(2025, 10, 22))) # "2025-26" (Opening Night) print(get_season_from_date(date(2025, 9, 30))) # "2024-25" (day before boundary) print(get_season_from_date(date(2025, 10, 1))) # "2025-26" (on the boundary) # season_start_year print(season_start_year("2025-26")) # 2025 print(season_start_year("2024-25")) # 2024 print(season_start_year("1999-00")) # 1999 # season_to_season_id print(season_to_season_id("2025-26")) # "22025" print(season_to_season_id("2024-25")) # "22024" print(season_to_season_id("1999-00")) # "21999" ``` -------------------------------- ### Fetch Single Endpoint using NBAClient.get() Source: https://github.com/reidhoch/fastbreak/blob/main/docs/client.md Explains and demonstrates the `get()` method of the NBAClient for fetching a single endpoint. It covers parameters like `endpoint` and `request_id`, the method's behavior including caching and retries, and returns a validated response model. Includes examples for basic fetching and tracing. ```python from fastbreak.clients import NBAClient from fastbreak.endpoints.box_scores_v3 import BoxScoreTraditionalV3 async def fetch_box_score(game_id: str) -> None: async with NBAClient() as client: box = await client.get(BoxScoreTraditionalV3(game_id=game_id)) for player in box.box_score_traditional.home_team.players: print(player.name_i, player.statistics.points) ``` ```python import uuid from fastbreak.clients import NBAClient async def fetch_with_trace(game_id: str, trace_id: str) -> None: async with NBAClient() as client: result = await client.get( BoxScoreTraditionalV3(game_id=game_id), request_id=trace_id, ) ``` -------------------------------- ### Quick Start: Matchup Analysis with fastbreak Source: https://github.com/reidhoch/fastbreak/blob/main/docs/matchups.md Demonstrates how to use the NBAClient to retrieve primary defenders for a specific player and generate team matchup summaries ranked by points per possession (PPP). ```python from fastbreak.clients import NBAClient from fastbreak.matchups import ( get_primary_defenders, get_team_matchup_summary, matchup_ppp, rank_matchups, ) async with NBAClient() as client: # Who guards Jayson Tatum the most? defenders = await get_primary_defenders( client, player_id=1628369, season="2025-26", top_n=5 ) for d in defenders: print(f"{d.def_player_name}: {d.matchup_min:.1f} min, {d.partial_poss:.1f} poss") # All Celtics-vs-Heat matchups, ranked by PPP summary = await get_team_matchup_summary( client, off_team_id=1610612738, def_team_id=1610612748, season="2025-26", ) ranked = rank_matchups(summary, min_poss=5.0, by="ppp", ascending=False) for m in ranked[:5]: ppp = matchup_ppp(m.player_pts, m.partial_poss) print(f"{m.off_player_name} vs {m.def_player_name}: {ppp:.2f} PPP") ``` -------------------------------- ### Testing NBAClient with aiohttp.test_utils Source: https://github.com/reidhoch/fastbreak/blob/main/docs/client.md This example shows how to use `aiohttp.test_utils.aiohttp_client` to create a test client that provides an `aiohttp.ClientSession`. This session can then be passed to `NBAClient` for testing purposes, allowing for mock servers or integration tests without making actual network requests. The `NBAClient` is still explicitly closed in a `finally` block to ensure cleanup. ```python from aiohttp.test_utils import TestClient, TestServer from fastbreak.clients import NBAClient async def test_with_mock_server(aiohttp_client, app) -> None: test_client = await aiohttp_client(app) nba = NBAClient(session=test_client.session, handle_signals=False) try: result = await nba.get(some_endpoint) assert result is not None finally: await nba.close() ``` -------------------------------- ### Set Logging Environment Variables in Shell (Bash) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Provides examples of setting the `FASTBREAK_LOG_LEVEL` and `FASTBREAK_LOG_FORMAT` environment variables in a shell before running a Python script. This configures Fastbreak's structlog integration. ```bash export FASTBREAK_LOG_LEVEL=DEBUG export FASTBREAK_LOG_FORMAT=console python my_script.py ``` ```bash FASTBREAK_LOG_LEVEL=DEBUG python my_script.py ``` -------------------------------- ### Access Response Fields in fastbreak (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md This section explains how to access response fields from the NBA API using the fastbreak library. It highlights that response models use Python-style snake_case field names and are fully typed. The example shows how to access fields like game_date, matchup, pts, reb, ast, fg_pct, and wl. ```python # All of these are typed str | int | float | None — no guessing game.game_date # "FEB 26, 2026" game.matchup # "LAL vs. MEM" game.pts # 28 game.reb # 7 game.ast # 10 game.fg_pct # 0.537 game.wl # "W" ``` -------------------------------- ### Call Endpoints Directly with fastbreak (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md This code demonstrates how to call NBA API endpoints directly using the fastbreak library. It constructs a PlayerCareerStats endpoint and uses the client.get() method to fetch career statistics for LeBron James. The example iterates through the last five seasons and prints the season ID, team abbreviation, games played, points, rebounds, and assists. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.endpoints import PlayerCareerStats async def main(): async with NBAClient() as client: career = await client.get( PlayerCareerStats(player_id=2544, per_mode="PerGame") ) for season in career.season_totals_regular_season[-5:]: print( f"{season.season_id} {season.team_abbreviation}" f" {season.gp} GP {season.pts} / {season.reb} / {season.ast}" ) asyncio.run(main()) ``` -------------------------------- ### Analyze game-level transition statistics Source: https://github.com/reidhoch/fastbreak/blob/main/docs/transition.md Uses the NBAClient to fetch game data and compute overall transition versus half-court efficiency metrics using the get_transition_stats helper. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.transition import get_transition_stats async def main(): async with NBAClient() as client: analysis = await get_transition_stats(client, "0022500571") s = analysis.summary e = analysis.efficiency print(f"Possessions: {s.total_possessions}") print(f"Transition: {s.transition_possessions} ({s.transition_pct:.1%})") print(f"Half-court: {s.halfcourt_possessions} ({s.halfcourt_pct:.1%})") if e.transition_ppp is not None and e.halfcourt_ppp is not None: diff = e.transition_ppp - e.halfcourt_ppp label = "more" if diff > 0 else "less" print(f"Transition PPP: {e.transition_ppp:.2f}") print(f"Half-court PPP: {e.halfcourt_ppp:.2f}") print(f"Transition is {abs(diff):.2f} PPP {label} efficient") asyncio.run(main()) ``` -------------------------------- ### GET /player_dashboard_by_general_splits Source: https://github.com/reidhoch/fastbreak/blob/main/docs/endpoints.md Retrieves stats split by location, W/L, month, pre/post All-Star, starting position, and days of rest. ```APIDOC ## GET /player_dashboard_by_general_splits ### Description Retrieves stats split by location, W/L, month, pre/post All-Star, starting position, and days of rest. ### Method GET ### Endpoint /player_dashboard_by_general_splits ### Parameters #### Query Parameters - **player_id** (int) - Required - The player ID. - **[Dashboard Filters]** (various) - Optional - Supports the full suite of dashboard filters (location, date range, opponent, etc.). ### Request Example { "player_id": 123, "location": "Home" } ### Response #### Success Response (200) - **PlayerDashboardByGeneralSplitsResponse** (object) - Player dashboard by general splits data. #### Response Example { "PlayerDashboardByGeneralSplitsResponse": { ... } } ``` -------------------------------- ### Quick Start: NBA Lineup Analysis Source: https://github.com/reidhoch/fastbreak/blob/main/docs/lineups.md Demonstrates how to use the fastbreak.lineups module to fetch top lineups, analyze lineup efficiency, and retrieve two-man combinations for a specific team. Requires an initialized NBAClient. ```python from fastbreak.clients import NBAClient from fastbreak.lineups import ( get_league_lineups, get_lineup_efficiency, get_top_lineups, get_two_man_combos, lineup_net_rating, rank_lineups, ) async with NBAClient() as client: # Top 10 five-man lineups for the Lakers by plus/minus top = await get_top_lineups(client, 1610612747, top_n=10, min_minutes=10.0) # Lakers lineup efficiency (sorted by net rating) best = await get_lineup_efficiency(client, team_id=1610612747, top_n=5) # Two-man combos for a specific team combos = await get_two_man_combos(client, team_id=1610612747) ranked = rank_lineups(combos, min_minutes=5.0, by="plus_minus") ``` -------------------------------- ### aiohttp Web App Lifespan Management for NBAClient Source: https://github.com/reidhoch/fastbreak/blob/main/docs/client.md This example shows how to manage the NBAClient lifecycle in an aiohttp web application. It defines `on_startup` and `on_cleanup` asynchronous functions to create and close the NBAClient, respectively. The client instance is stored in the application's state dictionary for access within request handlers. Similar to the FastAPI example, `handle_signals=False` is used. ```python from aiohttp import web from fastbreak.clients import NBAClient async def on_startup(app: web.Application) -> None: app["nba"] = NBAClient(handle_signals=False) async def on_cleanup(app: web.Application) -> None: await app["nba"].close() app = web.Application() app.on_startup.append(on_startup) app.on_cleanup.append(on_cleanup) ``` -------------------------------- ### Disable Retries in Python Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Demonstrates how to completely disable retries by setting `max_retries=0`. Any failures will raise exceptions immediately without any retry attempts. ```python async with NBAClient(max_retries=0) as client: result = await client.get(...) # raises on first failure, no retries ``` -------------------------------- ### Get Full Transition Analysis for a Game (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/transition.md An asynchronous convenience wrapper that fetches play-by-play data, classifies possessions, and computes transition frequency and efficiency for a given game ID. It orchestrates calls to `get_play_by_play`, `classify_possessions`, `transition_frequency`, and `transition_efficiency`. Requires an active `NBAClient` and a game ID. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.transition import get_transition_stats async def main(): async with NBAClient() as client: analysis = await get_transition_stats(client, "0022500571") s = analysis.summary e = analysis.efficiency print(f"Total possessions: {s.total_possessions}") print(f"Transition rate: {s.transition_pct:.1%}") print(f"Transition PPP: {e.transition_ppp:.2f}") print(f"Half-court PPP: {e.halfcourt_ppp:.2f}") asyncio.run(main()) ``` -------------------------------- ### Check Cache Status When Disabled (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Shows how to check the cache status when caching is disabled (`cache_ttl=0`). In this scenario, `client.cache_info` returns `None`, indicating that no caching is active. ```python async with NBAClient() as client: # cache_ttl=0, caching disabled print(client.cache_info) # None ``` -------------------------------- ### Quick Start: Fetching Estimated Metrics Source: https://github.com/reidhoch/fastbreak/blob/main/docs/estimated.md Demonstrates the initialization of the NBAClient and the retrieval of player leaders, specific player metrics, and team metrics using the fastbreak library. ```python from fastbreak.clients import NBAClient from fastbreak.estimated import ( get_player_estimated_metrics, get_team_estimated_metrics, get_estimated_leaders, find_player, find_team, rank_estimated_metrics, ) async with NBAClient() as client: # Top 10 players by estimated net rating (2025-26 season) leaders = await get_estimated_leaders(client, metric="e_net_rating", top_n=10, min_gp=20) for rank, p in enumerate(leaders, 1): print(f"{rank}. {p.player_name}: {p.e_net_rating:+.1f}") # Single player lookup players = await get_player_estimated_metrics(client, season="2025-26") hali = find_player(players, player_id=1641705) if hali: print(f"{hali.player_name}: OFF {hali.e_off_rating:.1f} / DEF {hali.e_def_rating:.1f}") # Team metrics teams = await get_team_estimated_metrics(client, season="2025-26") pacers = find_team(teams, team_id=1610612754) if pacers: print(f"{pacers.team_name}: pace {pacers.e_pace:.1f}") ``` -------------------------------- ### Configure Fewer Retries for Fast Failure (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Illustrates setting `max_retries` to 1 for interactive use or development, enabling faster failure when requests are expected to succeed immediately. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.endpoints import LeagueStandings async def main(): # Fewer retries — fail fast during development async with NBAClient(max_retries=1) as client: standings = await client.get(LeagueStandings(season="2025-26")) print(standings.standings[0].team_name) asyncio.run(main()) ``` -------------------------------- ### Construct and Use Endpoints with NBAClient in Python Source: https://github.com/reidhoch/fastbreak/blob/main/docs/endpoints.md This example demonstrates how to instantiate endpoints with specific parameters and use them with the `NBAClient` for single or multiple API requests. It highlights the asynchronous nature of the client. ```python from fastbreak.clients import NBAClient from fastbreak.endpoints import PlayerGameLog, PlayerCareerStats, BoxScoreTraditionalV3 async with NBAClient() as client: # Single request log = await client.get(PlayerGameLog(player_id=2544, season="2024-25")) # Multiple requests concurrently — all endpoints must return the same response type log1, log2 = await client.get_many([ PlayerGameLog(player_id=2544, season="2024-25"), PlayerGameLog(player_id=201939, season="2024-25"), ]) ``` -------------------------------- ### NBAClient Constructor Source: https://github.com/reidhoch/fastbreak/blob/main/docs/client.md Configuration options for initializing the NBAClient. ```APIDOC ## NBAClient Constructor ### Description Initializes the NBAClient with various configuration options for managing API requests, including session management, timeouts, retries, caching, and signal handling. ### Method `NBAClient(...)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Default | Description | |---|---|---|---| | `session` | `ClientSession | None` | `None` | Bring your own `aiohttp` session. When provided the client will **not** close it on exit. Useful for connection reuse or testing. | | `timeout` | `ClientTimeout | None` | `None` | Request timeout configuration. Defaults to `ClientTimeout(total=60)` (60-second total timeout). | | `max_retries` | `int` | `3` | Maximum number of retry attempts for transient failures. The first attempt counts; `max_retries=3` means up to 4 total attempts. | | `retry_wait_min` | `float` | `1.0` | Minimum wait in seconds between retries (lower bound for exponential backoff). | | `retry_wait_max` | `float` | `10.0` | Maximum wait in seconds between retries (upper bound for exponential backoff, also caps `Retry-After` values). | | `request_delay` | `float` | `0.0` | Seconds to sleep after each request inside `get_many()`, while holding the concurrency slot. Use for proactive rate limiting. Has no effect on `get()`. | | `cache_ttl` | `int` | `0` | TTL in seconds for the response cache. `0` disables caching entirely. | | `cache_maxsize` | `int` | `256` | Maximum number of responses to keep in the cache. Oldest entries are evicted when full. | | `handle_signals` | `bool` | `True` | Register `SIGINT`/`SIGTERM` handlers for graceful shutdown. Set to `False` when the process already manages signal handling (e.g., FastAPI, aiohttp app server). | ### Request Example ```python from aiohttp import ClientTimeout from fastbreak.clients import NBAClient # Example with custom timeout timeout = ClientTimeout(total=30, connect=5) client = NBAClient(timeout=timeout) # Example with existing session # async with aiohttp.ClientSession() as session: # client = NBAClient(session=session) # Example with signal handling disabled # client = NBAClient(handle_signals=False) ``` ### Response #### Success Response (200) N/A (Constructor does not return a value directly, it initializes the client object) #### Response Example N/A ``` -------------------------------- ### Configure Increased Retries for Batch Jobs (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Shows how to increase `max_retries` to 5 and adjust the backoff window for batch jobs that can tolerate more retries. This is useful for handling rate-limited APIs. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.endpoints import LeagueStandings async def main(): # More retries, tighter backoff window — good for rate-limited batch jobs async with NBAClient( max_retries=5, retry_wait_min=2.0, retry_wait_max=30.0, ) as client: standings = await client.get(LeagueStandings(season="2025-26")) print(f"Fetched {len(standings.standings)} teams") asyncio.run(main()) ``` -------------------------------- ### GET /player/general-splits Source: https://github.com/reidhoch/fastbreak/blob/main/docs/splits.md Retrieves situational player statistics categorized by game location, outcome, month, All-Star break status, starting position, and rest days. ```APIDOC ## GET /player/general-splits ### Description Fetch player situational splits by location, game outcome, month, All-Star break, starting position, and days of rest. ### Method GET ### Endpoint /player/general-splits ### Parameters #### Query Parameters - **player_id** (int) - Required - The unique identifier for the NBA player. - **season** (Season) - Optional - The specific NBA season to query. ### Response #### Success Response (200) - **overall** (GameSplitStats) - Full-season aggregate. - **by_location** (list) - Home vs. Road splits. - **by_wins_losses** (list) - Wins vs. Losses splits. - **by_month** (list) - Stats per calendar month. - **by_pre_post_all_star** (list) - Pre vs. Post All-Star break stats. - **by_starting_position** (list) - Starters vs. Bench stats. - **by_days_rest** (list) - Stats by days of rest (0/1/2/3+). ``` -------------------------------- ### Compare transition windows Source: https://github.com/reidhoch/fastbreak/blob/main/docs/transition.md Evaluates how different transition time windows affect the classification and frequency of transition possessions within a game. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.games import get_play_by_play from fastbreak.transition import classify_possessions, transition_frequency async def main(): async with NBAClient() as client: actions = await get_play_by_play(client, "0022500571") for window in [4.0, 6.0, 8.0, 10.0]: poss = classify_possessions(actions, transition_window=window) s = transition_frequency(poss) pct = f"{s.transition_pct:.1%}" if s.transition_pct is not None else "N/A" print(f"Window {window:.0f}s: {s.transition_possessions} transition ({pct})") asyncio.run(main()) ``` -------------------------------- ### Standard Usage with Async Context Manager Source: https://github.com/reidhoch/fastbreak/blob/main/docs/client.md Demonstrates the recommended way to use NBAClient with an async context manager for automatic session handling. ```APIDOC ## Standard Usage with Async Context Manager ### Description This pattern utilizes the `async with` statement to ensure the NBAClient's session is properly managed, opened lazily on the first request, and automatically closed upon exiting the block. ### Method `async with NBAClient() as client:` ### Endpoint N/A (This describes client initialization and usage, not a specific endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.endpoints.scoreboard_v2 import ScoreboardV2 async def main() -> None: async with NBAClient() as client: scoreboard = await client.get(ScoreboardV2(game_date="2026-02-27")) for game in scoreboard.game_header: print(game.game_id, game.home_team_id, game.visitor_team_id) asyncio.run(main()) ``` ### Response #### Success Response (200) Returns the Pydantic model corresponding to the requested endpoint (e.g., `ScoreboardV2` model in the example). #### Response Example ```json { "game_id": "0022600001", "home_team_id": 1610612744, "visitor_team_id": 1610612745 } ``` ``` -------------------------------- ### Convert API Responses to Polars DataFrame (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Illustrates how to convert API response models with `PolarsMixin` into a polars DataFrame. The `to_polars()` class method is used with a list of model instances to generate a DataFrame, facilitating efficient data processing and analysis with polars. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.endpoints import LeagueStandings from fastbreak.models import TeamStanding async def main(): async with NBAClient() as client: standings = await client.get(LeagueStandings(season="2025-26")) df = TeamStanding.to_polars(standings.standings) print(df.select(["team_name", "wins", "losses", "win_pct"])).head(10) ``` -------------------------------- ### Manual NBAClient Lifecycle Management (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/client.md Illustrates how to use NBAClient without the async context manager, requiring manual calls to `close()`. This pattern is necessary when `async with` cannot be used. A `ResourceWarning` is issued if the client is garbage-collected without being closed. ```python from fastbreak.clients import NBAClient client = NBAClient(handle_signals=False) try: result = await client.get(some_endpoint) finally: await client.close() ``` -------------------------------- ### Convert API Responses to Pandas DataFrame (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Shows how to convert API response models that include `PandasMixin` into a pandas DataFrame. The `to_pandas()` class method is called with a list of model instances, creating a DataFrame where each row represents an item from the response. This is useful for data analysis and manipulation. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.endpoints import LeagueStandings from fastbreak.models import TeamStanding async def main(): async with NBAClient() as client: standings = await client.get(LeagueStandings(season="2025-26")) # Pass the list of model instances to the class method df = TeamStanding.to_pandas(standings.standings) print(df[["team_name", "wins", "losses", "win_pct"]].head(10)) ``` -------------------------------- ### Quick Start: NBA Defense Analysis with fastbreak Source: https://github.com/reidhoch/fastbreak/blob/main/docs/defense.md Demonstrates initializing an NBAClient and using various defense functions to retrieve and analyze team defensive stats, opponent shooting breakdowns, and defensive box scores for specified games. It shows how to process the returned data for insights. ```python from fastbreak.clients import NBAClient from fastbreak.defense import ( get_team_defense_zones, get_team_opponent_stats, get_box_scores_defensive, defensive_shot_quality_vs_league, ) async with NBAClient() as client: # FG% allowed vs league average for all 30 teams (2025-26 season) zones = await get_team_defense_zones(client, season="2025-26") # Delta vs. league average for one team (Boston Celtics) deltas = defensive_shot_quality_vs_league(zones, team_id=1610612738) for abbr, delta in deltas.items(): print(f"{abbr}: {delta:+.3f} vs league avg (negative = better defense)") # Opponent 2PT/3PT shooting breakdown for all teams opp_stats = await get_team_opponent_stats(client, season="2025-26") bos = next(t for t in opp_stats if t.team_abbreviation == "BOS") print(f"BOS opp FG%: {bos.fg_pct:.1%} opp 3PT%: {bos.fg3_pct:.1%}") # Defensive box scores for specific games game_ids = ["0022500001", "0022500002"] boxes = await get_box_scores_defensive(client, game_ids) for gid, box in boxes.items(): home = box.box_score_defensive.home_team if home: print(f"{gid}: home team {home.team_tricode}") ``` -------------------------------- ### Enable and Configure In-Memory Caching (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Demonstrates how to enable and configure the in-memory caching mechanism in `fastbreak`. By setting `cache_ttl` to a positive integer (seconds) and optionally `cache_maxsize`, responses are cached to avoid redundant API calls. The cache is invalidated using `clear_cache()`, and its state can be inspected via `cache_info`. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.endpoints import LeagueStandings async def main(): # Cache responses for 5 minutes, hold up to 256 entries async with NBAClient(cache_ttl=300, cache_maxsize=256) as client: # First call hits the API s1 = await client.get(LeagueStandings(season="2025-26")) # Second call returns the cached response instantly s2 = await client.get(LeagueStandings(season="2025-26")) # s1 and s2 are the same object assert s1 is s2 # Inspect cache state print(client.cache_info) # {'size': 1, 'maxsize': 256, 'ttl': 300} # Manually invalidate all cached entries client.clear_cache() print(client.cache_info) # {'size': 0, 'maxsize': 256, 'ttl': 300} asyncio.run(main()) ``` -------------------------------- ### NBAClient: Async API Requests and Batching Source: https://context7.com/reidhoch/fastbreak/llms.txt Demonstrates using the `NBAClient` as an async context manager to make single and batch requests to the NBA Stats API. It shows how to fetch player game logs and box scores, with automatic response parsing into typed Pydantic models. Requires `fastbreak.clients` and specific endpoint models. ```python import asyncio from fastbreak.clients import NBAClient from fastbreak.endpoints import PlayerGameLog, BoxScoreTraditionalV3 async def main(): async with NBAClient() as client: # Single request - returns typed response model log = await client.get( PlayerGameLog( player_id=2544, # LeBron James season="2024-25", season_type="Regular Season", ) ) for game in log.games[:5]: print(f"{game.game_date}: {game.pts} pts, {game.reb} reb, {game.ast} ast") # Batch requests - all endpoints must have same response type game_ids = ["0022500571", "0022500572", "0022500573"] results = await client.get_many( [BoxScoreTraditionalV3(game_id=gid) for gid in game_ids] ) for gid, result in zip(game_ids, results): home = result.box_score_traditional.home_team print(f"Game {gid}: {home.team_tricode} scored {home.statistics.points}") asyncio.run(main()) ``` -------------------------------- ### Control DataFrame Flattening and Separator (Python) Source: https://github.com/reidhoch/fastbreak/blob/main/docs/getting-started.md Explains how to control the flattening of nested model fields when converting to DataFrames. By default, nested fields like `statistics.points` become dot-separated columns. Setting `flatten=False` keeps nested objects as dictionary columns, and the `sep` parameter allows customization of the separator. ```python # Flat columns: "statistics.points", "statistics.rebounds", ... df = TraditionalPlayer.to_pandas(players, flatten=True, sep=".") # Dict columns: df["statistics"] is a dict df = TraditionalPlayer.to_pandas(players, flatten=False) ```