← كل الأدلة

صفحات ملفات السائقين مع الإحصاءات المهنية

اجمع ملف السائق وإجمالياته المهنية في بطاقة واحدة، بالاعتماد على رقم السباق.

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
}

تُحسب الإجماليات المهنية من المواسم المتاحة في الواجهة، وليس من مسيرة السائق كاملة. وسمها بما يناسب، مثل «منذ 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

استخدم rider_number كمعرّف في الرابط (/riders/93/)؛ فهو ما يبحث عنه المشجعون.

تعامل مع البيانات الناقصة

  • قد تكون image_url بقيمة null. اعرض رقم السباق في شارة ملوّنة بدلًا من صورة معطوبة.
  • يعيد الرقم غير المستخدم الحالة 404؛ اعرض صفحة «السائق غير موجود» بدلًا من خطأ.
  • يغيّر السائقون أرقامهم أحيانًا بين المواسم. إذا كنت تحفظ المفضلة، فاحفظ الرقم مع الموسم الذي أُخذ منه.
الدليل التالي → روزنامة الموسم والسباق القادم والنتائج