Practical code examples for common analysis tasks
Filter matches to find a specific team's home victories in a season.
GET /api/matches?season=2024&team=Forge
import requests
def get_forge_home_wins_2024():
"""Find all Forge FC home wins in the 2024 season."""
url = "https://canadasoccerapi.com/api/matches"
params = {"season": 2024, "team": "Forge", "limit": 500}
response = requests.get(url, params=params)
data = response.json()
# Filter for home wins
home_wins = [
match for match in data["matches"]
if match["home_team"] == "Forge FC"
and match["home_goals"] > match["away_goals"]
]
print(f"Forge FC Home Wins in 2024: {len(home_wins)}")
for match in home_wins:
print(f" {match['date']}: Forge FC {match['home_goals']} - "
f"{match['away_goals']} {match['away_team']}")
return home_wins
# Execute
wins = get_forge_home_wins_2024()
async function getForgeHomeWins2024() {
const url = 'https://canadasoccerapi.com/api/matches?season=2024&team=Forge&limit=500';
const response = await fetch(url);
const data = await response.json();
// Filter for home wins
const homeWins = data.matches.filter(match =>
match.home_team === 'Forge FC' &&
match.home_goals > match.away_goals
);
console.log(`Forge FC Home Wins in 2024: ${homeWins.length}`);
homeWins.forEach(match => {
console.log(` ${match.date}: Forge FC ${match.home_goals} - ${match.away_goals} ${match.away_team}`);
});
return homeWins;
}
// Execute
getForgeHomeWins2024();
Forge FC Home Wins in 2024: 11
2024-04-13: Forge FC 3 - 1 Atletico Ottawa
2024-04-27: Forge FC 2 - 0 Valour FC
2024-05-11: Forge FC 4 - 2 Pacific FC
...
Analyze historical matchups between two specific teams.
import requests
def head_to_head(team1: str, team2: str):
"""Calculate head-to-head record between two teams."""
url = "https://canadasoccerapi.com/api/matches"
response = requests.get(url, params={"team": team1, "limit": 500})
matches = response.json()["matches"]
# Filter to matches between the two teams
h2h_matches = [
m for m in matches
if (team1.lower() in m["home_team"].lower() or team1.lower() in m["away_team"].lower())
and (team2.lower() in m["home_team"].lower() or team2.lower() in m["away_team"].lower())
]
team1_wins, team2_wins, draws = 0, 0, 0
for match in h2h_matches:
is_team1_home = team1.lower() in match["home_team"].lower()
team1_goals = match["home_goals"] if is_team1_home else match["away_goals"]
team2_goals = match["away_goals"] if is_team1_home else match["home_goals"]
if team1_goals > team2_goals:
team1_wins += 1
elif team2_goals > team1_goals:
team2_wins += 1
else:
draws += 1
print(f"\n=== {team1} vs {team2} Head-to-Head ===")
print(f"Total matches: {len(h2h_matches)}")
print(f"{team1} wins: {team1_wins}")
print(f"{team2} wins: {team2_wins}")
print(f"Draws: {draws}")
return {"team1_wins": team1_wins, "team2_wins": team2_wins, "draws": draws}
# Execute
head_to_head("Forge", "Cavalry")
async function headToHead(team1, team2) {
const url = `https://canadasoccerapi.com/api/matches?team=${team1}&limit=500`;
const response = await fetch(url);
const data = await response.json();
// Filter to head-to-head matches
const h2hMatches = data.matches.filter(m =>
(m.home_team.toLowerCase().includes(team1.toLowerCase()) ||
m.away_team.toLowerCase().includes(team1.toLowerCase())) &&
(m.home_team.toLowerCase().includes(team2.toLowerCase()) ||
m.away_team.toLowerCase().includes(team2.toLowerCase()))
);
let team1Wins = 0, team2Wins = 0, draws = 0;
h2hMatches.forEach(match => {
const isTeam1Home = match.home_team.toLowerCase().includes(team1.toLowerCase());
const team1Goals = isTeam1Home ? match.home_goals : match.away_goals;
const team2Goals = isTeam1Home ? match.away_goals : match.home_goals;
if (team1Goals > team2Goals) team1Wins++;
else if (team2Goals > team1Goals) team2Wins++;
else draws++;
});
console.log(`\n=== ${team1} vs ${team2} Head-to-Head ===`);
console.log(`Total matches: ${h2hMatches.length}`);
console.log(`${team1} wins: ${team1Wins}`);
console.log(`${team2} wins: ${team2Wins}`);
console.log(`Draws: ${draws}`);
return { team1Wins, team2Wins, draws };
}
headToHead('Forge', 'Cavalry');
=== Forge vs Cavalry Head-to-Head ===
Total matches: 24
Forge wins: 10
Cavalry wins: 8
Draws: 6
Monitor team performance evolution using standings data.
GET /api/standings
import requests
def goal_difference_trends(team_name: str):
"""Track a team's goal difference across all seasons."""
url = "https://canadasoccerapi.com/api/standings"
response = requests.get(url)
data = response.json()
print(f"\n=== {team_name} Goal Difference Trend ===\n")
print(f"{'Season':<8} {'GF':<5} {'GA':<5} {'GD':<6} {'Position'}")
print("-" * 35)
for season in sorted(data["seasons"]):
standings = data["standings"][str(season)]
team_data = next(
(t for t in standings if team_name.lower() in t["team"].lower()),
None
)
if team_data:
gd = team_data['goal_difference']
gd_str = f"+{gd}" if gd > 0 else str(gd)
print(f"{season:<8} {team_data['goals_for']:<5} "
f"{team_data['goals_against']:<5} "
f"{gd_str:<6} #{team_data['position']}")
# Execute
goal_difference_trends("Forge")
async function goalDifferenceTrends(teamName) {
const url = 'https://canadasoccerapi.com/api/standings';
const response = await fetch(url);
const data = await response.json();
console.log(`\n=== ${teamName} Goal Difference Trend ===\n`);
console.log('Season GF GA GD Position');
console.log('-'.repeat(35));
data.seasons.sort().forEach(season => {
const standings = data.standings[season];
const teamData = standings.find(t =>
t.team.toLowerCase().includes(teamName.toLowerCase())
);
if (teamData) {
const gdStr = teamData.goal_difference >= 0 ?
`+${teamData.goal_difference}` : `${teamData.goal_difference}`;
console.log(`${season} ${teamData.goals_for} ${teamData.goals_against} ${gdStr} #${teamData.position}`);
}
});
}
goalDifferenceTrends('Forge');
=== Forge Goal Difference Trend ===
Season GF GA GD Position
-----------------------------------
2019 50 29 +21 #1
2020 25 14 +11 #1
2021 42 28 +14 #1
2022 45 32 +13 #2
2023 48 30 +18 #1
2024 52 28 +24 #1
Generate GeoJSON data for mapping CPL team locations.
GET /api/teams?active_only=true
import requests
import json
def map_team_locations():
"""Generate GeoJSON for mapping CPL team locations."""
url = "https://canadasoccerapi.com/api/teams?active_only=true"
response = requests.get(url)
data = response.json()
# Generate GeoJSON
geojson = {
"type": "FeatureCollection",
"features": []
}
for team in data["teams"]:
if team.get("latitude") and team.get("longitude"):
feature = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [team["longitude"], team["latitude"]]
},
"properties": {
"name": team["name"],
"city": team["city"],
"stadium": team["stadium"],
"surface": team["surface"]
}
}
geojson["features"].append(feature)
print(f"Generated GeoJSON with {len(geojson['features'])} team locations")
# Save to file for use with Leaflet/Mapbox
with open("cpl_teams.geojson", "w") as f:
json.dump(geojson, f, indent=2)
return geojson
map_team_locations()
async function mapTeamLocations() {
const url = 'https://canadasoccerapi.com/api/teams?active_only=true';
const response = await fetch(url);
const data = await response.json();
// Generate GeoJSON
const geojson = {
type: 'FeatureCollection',
features: data.teams
.filter(team => team.latitude && team.longitude)
.map(team => ({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [team.longitude, team.latitude]
},
properties: {
name: team.name,
city: team.city,
stadium: team.stadium,
surface: team.surface
}
}))
};
console.log(`Generated GeoJSON with ${geojson.features.length} team locations`);
// Can be used with Leaflet, Mapbox, etc.
return geojson;
}
mapTeamLocations();
Compare team performance at home versus on the road.
GET /api/matches?season=2024&limit=500
import requests
from collections import defaultdict
def home_vs_away_analysis(season: int):
"""Analyze home vs away performance for all teams."""
url = "https://canadasoccerapi.com/api/matches"
response = requests.get(url, params={"season": season, "limit": 500})
matches = response.json()["matches"]
stats = defaultdict(lambda: {
"home": {"played": 0, "wins": 0, "draws": 0, "losses": 0},
"away": {"played": 0, "wins": 0, "draws": 0, "losses": 0}
})
for match in matches:
home, away = match["home_team"], match["away_team"]
hg, ag = match["home_goals"], match["away_goals"]
stats[home]["home"]["played"] += 1
stats[away]["away"]["played"] += 1
if hg > ag:
stats[home]["home"]["wins"] += 1
stats[away]["away"]["losses"] += 1
elif ag > hg:
stats[home]["home"]["losses"] += 1
stats[away]["away"]["wins"] += 1
else:
stats[home]["home"]["draws"] += 1
stats[away]["away"]["draws"] += 1
print(f"\n=== {season} Home vs Away Performance ===\n")
for team, data in sorted(stats.items()):
h, a = data["home"], data["away"]
home_pts = h["wins"] * 3 + h["draws"]
away_pts = a["wins"] * 3 + a["draws"]
print(f"{team}: Home {h['wins']}-{h['draws']}-{h['losses']} ({home_pts}pts) | "
f"Away {a['wins']}-{a['draws']}-{a['losses']} ({away_pts}pts)")
home_vs_away_analysis(2024)
CPL typically shows ~15% higher win rate at home. Factors include travel distances, altitude (Calgary), and surface type familiarity.
Identify the most entertaining high-scoring games.
import requests
def find_highest_scoring_matches(top_n=10):
"""Find the highest-scoring matches in CPL history."""
url = "https://canadasoccerapi.com/api/matches"
all_matches = []
offset = 0
# Paginate to get all matches
while True:
response = requests.get(url, params={"limit": 500, "offset": offset})
data = response.json()
all_matches.extend(data["matches"])
if offset + data["count"] >= data["total"]:
break
offset += 500
# Sort by total goals
all_matches.sort(key=lambda m: m["home_goals"] + m["away_goals"], reverse=True)
print(f"\n=== Top {top_n} Highest-Scoring Matches ===\n")
for match in all_matches[:top_n]:
total = match["home_goals"] + match["away_goals"]
print(f"{match['date']}: {match['home_team']} {match['home_goals']}-"
f"{match['away_goals']} {match['away_team']} ({total} goals)")
avg = sum(m["home_goals"] + m["away_goals"] for m in all_matches) / len(all_matches)
print(f"\nAverage goals per match: {avg:.2f}")
find_highest_scoring_matches(10)
=== Top 10 Highest-Scoring Matches ===
2019-08-28: Pacific FC 5-4 HFX Wanderers FC (9 goals)
2021-07-17: Valour FC 6-2 FC Edmonton (8 goals)
2022-06-04: Forge FC 5-3 Pacific FC (8 goals)
...
Average goals per match: 2.73