Fahrerprofilseiten mit Karrierestatistiken
Kombinieren Sie Profil und Karrierebilanz eines Fahrers zu einer Profilkarte, abgerufen über die Startnummer.
8 Min. Lesezeit
Fan-Apps, Fantasy-Spiele und Nachrichtenseiten brauchen jeweils eine Seite pro Fahrer. Zwei Aufrufe liefern alles für eine Profilkarte: den Fahrer und seine Karrierebilanz.
Die zwei Aufrufe
GET /riders/93
GET /riders/93/career-stats
/riders/{rider_number} liefert das Profil:
{
"rider_number": 93,
"full_name": "Marc Márquez",
"nationality": "Spain",
"flag": "🇪🇸",
"birth_date": "1993-02-17",
"height_cm": 168,
"weight_kg": 59,
"team_name": "Gresini Racing MotoGP",
"image_url": null
}
/riders/{rider_number}/career-stats liefert die Gesamtwerte:
{
"rider_number": 93,
"rider_name": "Marc Márquez",
"total_wins": 44,
"total_podiums": 66,
"total_points": 1302,
"world_titles": 2,
"total_races": 118
}
Die Karrierewerte werden aus den in der API verfügbaren Saisons berechnet, nicht aus der gesamten Laufbahn eines Fahrers. Beschriften Sie sie entsprechend, zum Beispiel mit „Seit 2024“.
Beide parallel abrufen
import os
from concurrent.futures import ThreadPoolExecutor
from dataclasses import dataclass
from datetime import date
import requests
HOST = "motogp-api-championship-data-statistics.p.rapidapi.com"
HEADERS = {"X-RapidAPI-Key": os.environ["RAPIDAPI_KEY"], "X-RapidAPI-Host": HOST}
def get(path: str) -> dict:
res = requests.get(f"https://{HOST}{path}", headers=HEADERS, timeout=10)
res.raise_for_status()
return res.json()["data"]
@dataclass(frozen=True)
class RiderCard:
number: int
name: str
flag: str
team: str
age: int
wins: int
podiums: int
titles: int
races: int
@property
def podium_rate(self) -> float:
return self.podiums / self.races if self.races else 0.0
def age_on(birth: str, today: date) -> int:
born = date.fromisoformat(birth)
return today.year - born.year - ((today.month, today.day) < (born.month, born.day))
def rider_card(number: int) -> RiderCard:
with ThreadPoolExecutor(max_workers=2) as pool:
profile_f = pool.submit(get, f"/riders/{number}")
stats_f = pool.submit(get, f"/riders/{number}/career-stats")
profile, stats = profile_f.result(), stats_f.result()
return RiderCard(
number=profile["rider_number"],
name=profile["full_name"],
flag=profile["flag"],
team=profile["team_name"],
age=age_on(profile["birth_date"], date.today()),
wins=stats["total_wins"],
podiums=stats["total_podiums"],
titles=stats["world_titles"],
races=stats["total_races"],
)
card = rider_card(93)
print(f"{card.flag} #{card.number} {card.name} — {card.team}, {card.age}")
print(f"{card.wins} wins, {card.podiums} podiums in {card.races} races ({card.podium_rate:.0%})")
Die Indexseiten bauen
Profilseiten brauchen eine Liste, von der aus sie verlinkt werden:
| Seite | Endpunkt |
|---|---|
| Startfeld dieser Saison | GET /riders/seasons/{year}?category=MOTOGP |
| Fahrer nach Land | GET /riders/nationality/{nationality} (z. B. Italy) |
| Jeder Fahrer in der Datenbank | GET /riders?page=1&size=200 |
Verwenden Sie rider_number als URL-Slug (/riders/93/); danach suchen Fans.
Fehlende Daten behandeln
image_urlkannnullsein. Zeigen Sie statt eines defekten Bildes die Startnummer in einem farbigen Badge.- Eine nicht vergebene Nummer liefert
404– rendern Sie eine „Fahrer nicht gefunden“-Seite statt eines Fehlers. - Fahrer wechseln zwischen den Saisons manchmal die Nummer. Wenn Sie Favoriten speichern, speichern Sie die Nummer mit der Saison, aus der sie stammt.