Source code for livef1.models.circuit

from typing import Dict, Optional
import requests
import pandas as pd

from livef1.utils.constants import START_COORDINATES_URL
from livef1.utils.exceptions import livef1Exception


[docs] class Circuit: """ Represents a Formula 1 circuit with its characteristics and metadata. Attributes ---------- key : str The unique identifier for the circuit. short_name : str Short name/abbreviation of the circuit. name : str, optional Full name of the circuit. length : float, optional Length of the circuit in kilometers. laps : int, optional Standard number of race laps. country : Dict, optional Dictionary containing country information. location : str, optional Geographic location of the circuit. coordinates : Dict[str, float], optional Latitude and longitude of the circuit. """ def __init__( self, key: str, short_name: str ): self.key = key self.short_name = short_name def _load_start_coordinates(self): """ Load the start coordinates of the circuit from an external API. """ response = requests.get(START_COORDINATES_URL) if response.status_code == 200: data = response.json() try: self.start_coordinates = data[self.short_name]["start_coordinates"] self.start_direction = data[self.short_name]["start_direction"] except: pass else: raise Exception(f"Failed to load start coordinates: {response.status_code}") def _load_circuit_data(self): HEADERS = {'User-Agent': 'LiveF1/user'} response = requests.get("https://api.multiviewer.app/api/v1/circuits", headers=HEADERS) circuits = response.json() circuit_ref = next((v for v in circuits.values() if v.get('name').lower() == self.short_name.lower()), None) if circuit_ref == None: raise livef1Exception(f"Circut {self.short_name} couldn't be found in circuit api.") circuit_key = circuit_ref["circuitKey"] circuit_ref_years = circuit_ref["years"] response = requests.get(f"https://api.multiviewer.app/api/v1/circuits/{circuit_key}/{circuit_ref_years[0]}/", headers=HEADERS) self._raw_circuit_data = response.json() for corner in self._raw_circuit_data["corners"]: corner.update(corner["trackPosition"]) df_corners = pd.DataFrame(self._raw_circuit_data["corners"]).rename( columns = { "length": "Distance", "x": "X", "y": "Y" } ) df_corners.Distance = df_corners.Distance / 10 df_corners["corner_start"] = df_corners.Distance - 50 df_corners["corner_end"] = df_corners.Distance + 50 df_corners["corner_end"] = (df_corners["corner_end"] > df_corners["corner_start"].shift(-1).fillna(1000000)) * df_corners["corner_start"].shift(-1).fillna(0) + (df_corners["corner_end"] < df_corners["corner_start"].shift(-1).fillna(1000000)) * df_corners["corner_end"] df_corners["name"] = "T" + df_corners["number"].astype(int).astype(str) df_corners["type"] = "Corner" df_corners = df_corners[["type","name","number","X","Y","corner_start","corner_end","angle","Distance"]] df_straights = pd.DataFrame( { "corner_start" : df_corners.corner_end.shift(1).fillna(df_corners.corner_end.max()), "corner_end" : df_corners.corner_start, "number" : df_corners.number.shift(1).fillna(0).astype(int), } ) df_straights["type"] = "Straight" df_straights["name"] = "S" + df_straights["number"].astype(str) self.track_regions = pd.concat([df_corners, df_straights])