Fix NHL API adapter to handle actual API response structures
Corrected data parsing issues discovered during testing: Teams Endpoint: - Fixed get_all_teams to handle list response (not dict with "data" key) - Corrected team name parsing to avoid duplication - Properly extract city from full team name using common_name - Fixed division and conference extraction from nested dict structures Stats Endpoints: - Fixed game log parsing to handle list response (not dict with "gameLog" key) - Applied fix to both skater and goalie stats methods Testing Results: - Successfully retrieves all 32 NHL teams with correct names - Team lookup by abbreviation working correctly - Division and conference filtering operational - Player roster retrieval functional (28 players) - Player stats aggregation working (verified with Sammy Blais) All adapter methods now correctly transform NHL API responses to domain entities. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -110,11 +110,12 @@ class NHLPlayerAdapter(PlayerRepository):
|
|||||||
player_id=player_id, season_id=season_id, game_type=2
|
player_id=player_id, season_id=season_id, game_type=2
|
||||||
)
|
)
|
||||||
|
|
||||||
if not game_log or "gameLog" not in game_log:
|
# The API returns a list directly
|
||||||
|
if not game_log or not isinstance(game_log, list):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Aggregate stats from game log
|
# Aggregate stats from game log
|
||||||
return self._aggregate_skater_stats(player_id, game_log["gameLog"])
|
return self._aggregate_skater_stats(player_id, game_log)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error fetching skater stats for player {player_id}: {e}")
|
logger.error(f"Error fetching skater stats for player {player_id}: {e}")
|
||||||
@@ -136,11 +137,12 @@ class NHLPlayerAdapter(PlayerRepository):
|
|||||||
player_id=player_id, season_id=season_id, game_type=2
|
player_id=player_id, season_id=season_id, game_type=2
|
||||||
)
|
)
|
||||||
|
|
||||||
if not game_log or "gameLog" not in game_log:
|
# The API returns a list directly
|
||||||
|
if not game_log or not isinstance(game_log, list):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Aggregate stats from game log
|
# Aggregate stats from game log
|
||||||
return self._aggregate_goalie_stats(player_id, game_log["gameLog"])
|
return self._aggregate_goalie_stats(player_id, game_log)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error fetching goalie stats for player {player_id}: {e}")
|
logger.error(f"Error fetching goalie stats for player {player_id}: {e}")
|
||||||
@@ -395,11 +397,12 @@ class NHLTeamAdapter(TeamRepository):
|
|||||||
try:
|
try:
|
||||||
teams_data = self.client.teams.teams()
|
teams_data = self.client.teams.teams()
|
||||||
|
|
||||||
if not teams_data or "data" not in teams_data:
|
# The API returns a list directly, not a dict with "data" key
|
||||||
|
if not teams_data or not isinstance(teams_data, list):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
teams = []
|
teams = []
|
||||||
for team_data in teams_data["data"]:
|
for team_data in teams_data:
|
||||||
team = self._transform_team_data(team_data)
|
team = self._transform_team_data(team_data)
|
||||||
if team:
|
if team:
|
||||||
teams.append(team)
|
teams.append(team)
|
||||||
@@ -430,25 +433,39 @@ class NHLTeamAdapter(TeamRepository):
|
|||||||
def _transform_team_data(self, team_data: Dict[str, Any]) -> Optional[NHLTeam]:
|
def _transform_team_data(self, team_data: Dict[str, Any]) -> Optional[NHLTeam]:
|
||||||
"""Transforms NHL API team data to domain NHLTeam entity."""
|
"""Transforms NHL API team data to domain NHLTeam entity."""
|
||||||
try:
|
try:
|
||||||
team_name = team_data.get("fullName", "") or team_data.get("teamName", {}).get("default", "")
|
# API returns structure: {name, common_name, abbr, division:{name}, conference:{name}}
|
||||||
city_name = team_data.get("placeName", {}).get("default", "")
|
# name = "Colorado Avalanche", common_name = "Avalanche"
|
||||||
|
full_name = team_data.get("name", "")
|
||||||
|
common_name = team_data.get("common_name", "")
|
||||||
|
|
||||||
# Handle team name that might include city
|
# Extract city and team name
|
||||||
if not city_name and " " in team_name:
|
# The full_name includes city, common_name is just the team name
|
||||||
parts = team_name.rsplit(" ", 1)
|
if " " in full_name and common_name:
|
||||||
if len(parts) == 2:
|
# Split to get city (everything except the common_name at the end)
|
||||||
|
city_name = full_name.replace(common_name, "").strip()
|
||||||
|
team_name = common_name
|
||||||
|
elif " " in full_name:
|
||||||
|
# Fallback: split on last space
|
||||||
|
parts = full_name.rsplit(" ", 1)
|
||||||
city_name = parts[0]
|
city_name = parts[0]
|
||||||
team_name = parts[1]
|
team_name = parts[1]
|
||||||
|
else:
|
||||||
|
city_name = ""
|
||||||
|
team_name = full_name
|
||||||
|
|
||||||
|
# Extract division and conference from nested dicts
|
||||||
|
division_data = team_data.get("division", {})
|
||||||
|
conference_data = team_data.get("conference", {})
|
||||||
|
|
||||||
return NHLTeam(
|
return NHLTeam(
|
||||||
id=str(team_data.get("id", "")),
|
id=str(team_data.get("franchise_id", "")),
|
||||||
name=team_name,
|
name=team_name,
|
||||||
abbreviation=team_data.get("triCode", ""),
|
abbreviation=team_data.get("abbr", ""),
|
||||||
city=city_name,
|
city=city_name,
|
||||||
division=team_data.get("divisionName", ""),
|
division=division_data.get("name", "") if isinstance(division_data, dict) else "",
|
||||||
conference=team_data.get("conferenceName", ""),
|
conference=conference_data.get("name", "") if isinstance(conference_data, dict) else "",
|
||||||
venue_name=None, # Not provided in basic team data
|
venue_name=None, # Not provided in basic team data
|
||||||
is_active=team_data.get("isActive", True),
|
is_active=True, # All teams in current API are active
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error transforming team data: {e}")
|
logger.error(f"Error transforming team data: {e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user