Introduction
The Fantasy Basketball Analytics API is a Flask-based REST API that combines Yahoo Fantasy Sports data with NBA statistics to provide comprehensive fantasy basketball analytics. The API uses session-based authentication and returns all responses in JSON format.
Base URL Structure
The API runs on Flask’s development server with the following configuration:
app.run(debug=True, port=5000, host='0.0.0.0')
All API endpoints are prefixed with /api/ for data endpoints:
/api/scoreboard - Weekly matchup data
/api/season_avg - Season average statistics
/api/league_settings - League configuration
/api/draft/keepers - Keeper player information
/api/nba_players - NBA player roster data
/api/nba_player_stats/<player_id> - Individual player statistics
All API responses are returned in JSON format. The API uses Flask’s jsonify() function to ensure consistent JSON serialization:
Successful Response Example
{
"players": [
{
"id": 2544,
"full_name": "LeBron James",
"team_abbreviation": "LAL",
"position": "F"
}
]
}
Error Handling
The API implements consistent error handling patterns across all endpoints:
Authentication Errors
if "token" not in session:
return jsonify({"error": "authentication required"}), 401
Response:
{
"error": "authentication required"
}
Status Code: 401 Unauthorized
Missing League Context
if "league_key" not in session:
return jsonify({"error": "no league chosen"}), 400
Response:
{
"error": "no league chosen"
}
Status Code: 400 Bad Request
Yahoo API Errors
When Yahoo API calls fail, the error is caught and returned with appropriate status codes:
except requests.exceptions.HTTPError as e:
status_code = e.response.status_code if e.response is not None else 502
error_detail = "Failed to fetch keeper data from Yahoo."
try:
yahoo_error = e.response.json() if e.response is not None else None
except Exception:
yahoo_error = None
if isinstance(yahoo_error, dict):
error_detail = yahoo_error.get("error", {}).get("description", error_detail)
return jsonify({"error": error_detail}), status_code
Generic Server Errors
except Exception as e:
log.error(f"Error fetching data: {e}")
return jsonify({"error": str(e)}), 500
Status Code: 500 Internal Server Error
Always check the response status code. A 200 status indicates success, while 4xx codes indicate client errors (authentication, missing parameters) and 5xx codes indicate server errors.
Rate Limiting Considerations
The API currently does not implement rate limiting on the Flask application level. However, you must consider rate limits from external services:
Yahoo Fantasy Sports API
Yahoo Fantasy Sports API has rate limits that vary by endpoint. The API implements automatic token refresh to maintain session continuity:
def yahoo_api(rel_path: str, *, _retry: bool = True) -> Dict[str, Any]:
token = session["token"]
resp = requests.get(
f"https://fantasysports.yahooapis.com/{rel_path}",
headers={"Authorization": f"Bearer {token['access_token']}"},
params={"format": "json"},
timeout=20,
)
if resp.status_code == 401 and _retry:
_refresh_token()
return yahoo_api(rel_path, _retry=False)
resp.raise_for_status()
return resp.json()
NBA Stats API
The NBA Stats API (via nba_api library) may throttle requests. The application implements fallback mechanisms:
try:
player_data_df = playerindex.PlayerIndex(season=season_str, league_id="00").get_data_frames()[0]
except Exception as e:
# Fallback to static players list
active_players_basic = nba_static_players.get_active_players()
Implement client-side throttling when making repeated API calls to avoid hitting external API rate limits.
Session Configuration
The API uses Flask sessions with the following configuration:
app.secret_key = os.getenv("FLASK_SECRET_KEY", "dev-key")
app.config.update(
SESSION_COOKIE_SAMESITE="Lax",
SESSION_COOKIE_SECURE=False,
PERMANENT_SESSION_LIFETIME=60 * 60, # 1 hour
)
Sessions expire after 1 hour of inactivity. Ensure your client handles session expiration gracefully.