← 모든 가이드

시즌 캘린더, 다음 레이스, 결과

Python으로 "다음 레이스" 카운트다운이 있는 레이스 캘린더와 라운드별 결과 페이지를 만듭니다.

8분 분량

모든 레이싱 앱에는 캘린더가 필요합니다. 이 가이드는 레이스 엔드포인트로 세 가지를 만듭니다.

  1. 라운드 순서로 정렬된 전체 시즌 캘린더.
  2. 카운트다운이나 푸시 알림에 쓸 다음 레이스.
  3. 종료된 라운드의 공식 결과.

캘린더

GET /races/seasons/{year}는 한 카테고리의 시즌 전체 라운드를 반환합니다.

{
  "round_number": 12,
  "name": "Qatar Airways Grand Prix of Great Britain",
  "circuit_name": "Silverstone Circuit, Silverstone",
  "country": "United Kingdom",
  "flag": "🇬🇧",
  "category": "MOTOGP",
  "race_date": "2026-08-09",
  "season_year": 2026
}

라운드는 순서대로 반환되지 않으므로 round_number로 정렬하세요.

import os
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, **params):
    res = requests.get(f"https://{HOST}{path}", headers=HEADERS, params=params, timeout=10)
    res.raise_for_status()
    return res.json()["data"]


def calendar(year: int, category: str = "MOTOGP") -> list[dict]:
    races = get(f"/races/seasons/{year}", category=category)
    return sorted(races, key=lambda r: r["round_number"])


for race in calendar(2026):
    print(f"R{race['round_number']:>2}  {race['race_date']}  {race['flag']}  {race['name']}")
...
R 6  2026-05-17  🇪🇸  Monster Energy Grand Prix of Catalunya
...
R12  2026-08-09  🇬🇧  Qatar Airways Grand Prix of Great Britain
...

다음 레이스

race_date는 ISO 날짜(YYYY-MM-DD)이므로 문자열로 정렬하고 비교하거나 date.fromisoformat으로 파싱할 수 있습니다.

def next_race(races: list[dict], today: date) -> dict | None:
    upcoming = [r for r in races if date.fromisoformat(r["race_date"]) >= today]
    return upcoming[0] if upcoming else None


race = next_race(calendar(2026), date.today())
if race:
    days = (date.fromisoformat(race["race_date"]) - date.today()).days
    print(f"Next: {race['name']} at {race['circuit_name']} in {days} days")
else:
    print("Season finished")

라운드 결과

라운드가 열린 후에는 시즌과 라운드로 결과를 조회할 수 있습니다.

def results(year: int, round_number: int, category: str = "MOTOGP") -> list[dict]:
    rows = get(f"/races/seasons/{year}/round/{round_number}/results", category=category)
    return sorted(rows, key=lambda r: r["position"])


for row in results(2026, 1)[:3]:
    print(f"P{row['position']}  {row['rider_name']:<22} {row['team_name']:<32} +{row['points']} pts")
P1  Marco Bezzecchi        Aprilia Racing                   +25 pts
P2  ...
P3  Raúl Fernández         SuperFile Trackhouse MotoGP Team +16 pts

각 행에는 status가 있습니다. 순위가 매겨진 라이더는 FINISHED이고, 그 외에는 DNF나 DNS 같은 값입니다. 완주하지 못한 라이더는 순위가 매겨진 라이더 아래에 표시하세요.

레이스 후 폴링

결과는 레이스 주말이 끝난 뒤 추가됩니다. “결과가 나왔습니다” 알림을 보낸다면, 몇 초마다가 아니라 레이스 날짜 이후 30–60분마다 최신 라운드의 결과 엔드포인트를 폴링하세요. 빈 목록은 “아직”을 의미하며, 느린 폴링은 할당량을 충분히 여유 있게 유지해 줍니다. 캘린더에 없는 라운드는 404를 반환합니다.

def results_ready(year: int, round_number: int) -> bool:
    return len(results(year, round_number)) > 0

Moto2와 Moto3

위의 모든 함수에 category="MOTO2" 또는 category="MOTO3"을 전달할 수 있습니다. 라운드 번호와 날짜는 같은 캘린더를 따르므로, 통합 주말 뷰는 round_number 기준 병합으로 만들 수 있습니다.

다음 가이드 → MotoGP 판타지 리그 점수 계산하기