← 모든 가이드

커리어 통계가 포함된 라이더 프로필 페이지

라이더의 프로필과 커리어 합계를 레이스 넘버를 키로 하여 하나의 프로필 카드로 결합합니다.

8분 분량

팬 앱, 판타지 게임, 뉴스 사이트에는 라이더별 페이지가 필요합니다. 프로필 카드에 필요한 모든 것은 두 번의 호출로 얻을 수 있습니다. 바로 라이더 정보와 커리어 합계입니다.

두 번의 호출

GET /riders/93
GET /riders/93/career-stats

/riders/{rider_number}는 프로필을 반환합니다.

{
  "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는 합계를 반환합니다.

{
  "rider_number": 93,
  "rider_name": "Marc Márquez",
  "total_wins": 44,
  "total_podiums": 66,
  "total_points": 1302,
  "world_titles": 2,
  "total_races": 118
}

커리어 합계는 라이더의 전체 커리어가 아니라 API에서 제공하는 시즌을 기준으로 계산됩니다. 예를 들어 “2024년 이후”처럼 이를 표시하세요.

두 호출을 병렬로 가져오기

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%})")

인덱스 페이지 만들기

프로필 페이지로 연결하려면 목록이 필요합니다.

페이지엔드포인트
이번 시즌 그리드GET /riders/seasons/{year}?category=MOTOGP
국가별 라이더GET /riders/nationality/{nationality} (예: Italy)
데이터베이스의 모든 라이더GET /riders?page=1&size=200

URL 슬러그로는 rider_number(/riders/93/)를 사용하세요. 팬들이 검색하는 값이 바로 이것입니다.

누락된 데이터 처리하기

  • image_url은 null일 수 있습니다. 깨진 이미지 대신 색상이 있는 배지에 레이스 넘버를 표시하세요.
  • 사용되지 않는 번호는 404를 반환합니다. 오류 대신 “라이더를 찾을 수 없음” 페이지를 렌더링하세요.
  • 라이더는 시즌 사이에 번호를 바꾸기도 합니다. 즐겨찾기를 저장한다면 번호를 가져온 시즌과 함께 저장하세요.
다음 가이드 → 시즌 캘린더, 다음 레이스, 결과