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
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
# 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:
|
||||
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
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
# 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:
|
||||
logger.error(f"Error fetching goalie stats for player {player_id}: {e}")
|
||||
@@ -395,11 +397,12 @@ class NHLTeamAdapter(TeamRepository):
|
||||
try:
|
||||
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 []
|
||||
|
||||
teams = []
|
||||
for team_data in teams_data["data"]:
|
||||
for team_data in teams_data:
|
||||
team = self._transform_team_data(team_data)
|
||||
if team:
|
||||
teams.append(team)
|
||||
@@ -430,25 +433,39 @@ class NHLTeamAdapter(TeamRepository):
|
||||
def _transform_team_data(self, team_data: Dict[str, Any]) -> Optional[NHLTeam]:
|
||||
"""Transforms NHL API team data to domain NHLTeam entity."""
|
||||
try:
|
||||
team_name = team_data.get("fullName", "") or team_data.get("teamName", {}).get("default", "")
|
||||
city_name = team_data.get("placeName", {}).get("default", "")
|
||||
# API returns structure: {name, common_name, abbr, division:{name}, conference:{name}}
|
||||
# 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
|
||||
if not city_name and " " in team_name:
|
||||
parts = team_name.rsplit(" ", 1)
|
||||
if len(parts) == 2:
|
||||
city_name = parts[0]
|
||||
team_name = parts[1]
|
||||
# Extract city and team name
|
||||
# The full_name includes city, common_name is just the team name
|
||||
if " " in full_name and common_name:
|
||||
# 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]
|
||||
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(
|
||||
id=str(team_data.get("id", "")),
|
||||
id=str(team_data.get("franchise_id", "")),
|
||||
name=team_name,
|
||||
abbreviation=team_data.get("triCode", ""),
|
||||
abbreviation=team_data.get("abbr", ""),
|
||||
city=city_name,
|
||||
division=team_data.get("divisionName", ""),
|
||||
conference=team_data.get("conferenceName", ""),
|
||||
division=division_data.get("name", "") if isinstance(division_data, dict) else "",
|
||||
conference=conference_data.get("name", "") if isinstance(conference_data, dict) else "",
|
||||
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:
|
||||
logger.error(f"Error transforming team data: {e}")
|
||||
|
||||
Reference in New Issue
Block a user