Pylint added and changes reflected throughout

This commit is contained in:
Samuel Roach 2022-06-06 01:58:53 +01:00
parent 4ef3c06c15
commit 2a524596f9
25 changed files with 1281 additions and 776 deletions

5
.pylintrc Normal file
View File

@ -0,0 +1,5 @@
[MASTER]
disable=too-many-instance-attributes,
too-many-arguments,
too-many-locals

View File

@ -146,7 +146,7 @@ More detail on the available functions within the ``Ergast()`` class is availabl
<summary><b>RETURN</b> functions</summary>
</br>
> NOTE: All the return types that return a single object will raise an Exception if your query is returning more than one item.
> NOTE: All the functions that return a single object will raise an Exception if your query is returning more than one item.
| Name | Return Type |
| ------------------------- | --------------------- |

View File

@ -1,30 +1,60 @@
""" Expected class """
class Expected():
"""
Storage of the expected keys returned and their types
Representations of the types expected to be found within a model.
Each model has a set of keys, and the types expected.
Types are stored as one of the following strings:
* "int"
* "float"
* "string"
* "dict"
"""
location = {
@property
def location(self):
"""
Return the expected types of a Location
"""
return {
"lat": "float",
"long": "float",
"locality": "string",
"country": "string",
}
circuit = {
@property
def circuit(self):
"""
Return the expected types of a Circuit
"""
return {
"circuitId": "string",
"url": "string",
"circuitName": "string",
"Location": "string",
}
constructor = {
@property
def constructor(self):
"""
Return the expected types of a Constructor
"""
return {
"constructorId": "string",
"url": "string",
"name": "string",
"nationality": "string",
}
driver = {
@property
def driver(self):
"""
Return the expected types of a Driver
"""
return {
"driverId": "string",
"permanentNumber": "int",
"code": "string",
@ -35,7 +65,12 @@ class Expected():
"nationality": "string",
}
race = {
@property
def race(self):
"""
Return the expected types of a Race
"""
return {
"season": "int",
"round": "int",
"url": "string",
@ -55,7 +90,12 @@ class Expected():
"Laps": "dict",
}
result = {
@property
def result(self):
"""
Return the expected types of a Result
"""
return {
"number": "int",
"position": "int",
"positionText": "string",
@ -72,19 +112,34 @@ class Expected():
"Q3": "string",
}
fastest_lap = {
@property
def fastest_lap(self):
"""
Return the expected types of a Fastest Lap
"""
return {
"rank": "int",
"lap": "int",
"Time": "dict",
"AverageSpeed": "dict",
}
average_speed = {
@property
def average_speed(self):
"""
Return the expected types of a Average Speed
"""
return {
"units": "string",
"speed": "float",
}
pit_stop = {
@property
def pit_stop(self):
"""
Return the expected types of a Pit Stop
"""
return {
"driverId": "string",
"lap": "int",
"stop": "int",
@ -92,29 +147,54 @@ class Expected():
"duration": "string",
}
lap = {
@property
def lap(self):
"""
Return the expected types of a Lap
"""
return {
"number": "int",
"Timings": "dict",
}
timing = {
@property
def timing(self):
"""
Return the expected types of a Timing
"""
return {
"driverId": "string",
"position": "int",
"time": "string",
}
season = {
@property
def season(self):
"""
Return the expected types of a Season
"""
return {
"season": "int",
"url": "string",
}
status = {
@property
def status(self):
"""
Return the expected types of a Status
"""
return {
"statusId": "int",
"count": "int",
"status": "string"
}
driver_standing = {
@property
def driver_standing(self):
"""
Return the expected types of a Driver Standing
"""
return {
"position": "int",
"positionText": "string",
"points": "float",
@ -123,7 +203,12 @@ class Expected():
"Constructors": "dict"
}
constructor_standing = {
@property
def constructor_standing(self):
"""
Return the expected types of a Constructor Standing
"""
return {
"position": "int",
"positionText": "string",
"points": "float",
@ -131,7 +216,12 @@ class Expected():
"Constructor": "dict"
}
standings_list = {
@property
def standings_list(self):
"""
Return the expected types of a Standings List
"""
return {
"season": "int",
"round": "int",
"DriverStandings": "dict",

View File

@ -1,8 +1,16 @@
""" StatusType class """
class StatusType():
"""
A mapping of String onto the Status ID for that type
Mappings between ID and Strings for StatusType
"""
status_map = {
@property
def string_to_id(self):
"""
Return the map of StatusType strings to ids
"""
return {
"": 0,
"Finished": 1,
"Disqualified": 2,
@ -140,3 +148,147 @@ class StatusType():
"Debris": 138,
"Illness": 139,
}
@property
def id_to_string(self):
"""
Return the map of StatusType ids to strings
"""
return {
0 : "",
1: "Finished",
2: "Disqualified",
3: "Accident",
4: "Collision",
5: "Engine",
6: "Gearbox",
7: "Transmission",
8: "Clutch",
9: "Hydraulics",
10: "Electrical",
11: "+1 Lap",
12: "+2 Laps",
13: "+3 Laps",
14: "+4 Laps",
15: "+5 Laps",
16: "+6 Laps",
17: "+7 Laps",
18: "+8 Laps",
19: "+9 Laps",
20: "Spun off",
21: "Radiator",
22: "Suspension",
23: "Brakes",
24: "Differential",
25: "Overheating",
26: "Mechanical",
27: "Tyre",
28: "Driver Seat",
29: "Puncture",
30: "Driveshaft",
31: "Retired",
32: "Fuel pressure",
33: "Front wing",
34: "Water pressure",
35: "Refuelling",
36: "Wheel",
37: "Throttle",
38: "Steering",
39: "Technical",
40: "Electronics",
41: "Broken wing",
42: "Heat shield fire",
43: "Exhaust",
44: "Oil leak",
45: "+11 Laps",
46: "Wheel rim",
47: "Water leak",
48: "Fuel pump",
49: "Track rod",
50: "+17 Laps",
51: "Oil pressure",
53: "+13 Laps",
54: "Withdrew",
55: "+12 Laps",
56: "Engine fire",
58: "+26 Laps",
59: "Tyre puncture",
60: "Out of fuel",
61: "Wheel nut",
62: "Not classified",
63: "Pneumatics",
64: "Handling",
65: "Rear wing",
66: "Fire",
67: "Wheel bearing",
68: "Physical",
69: "Fuel system",
70: "Oil line",
71: "Fuel rig",
72: "Launch control",
73: "Injured",
74: "Fuel",
75: "Power loss",
76: "Vibrations",
77: "107% Rule",
78: "Safety",
79: "Drivetrain",
80: "Ignition",
81: "Did not qualify",
82: "Injury",
83: "Chassis",
84: "Battery",
85: "Stalled",
86: "Halfshaft",
87: "Crankshaft",
88: "+10 Laps",
89: "Safety concerns",
90: "Not restarted",
91: "Alternator",
92: "Underweight",
93: "Safety belt",
94: "Oil pump",
95: "Fuel leak",
96: "Excluded",
97: "Did not prequalify",
98: "Injection",
99: "Distributor",
100: "Driver unwell",
101: "Turbo",
102: "CV joint",
103: "Water pump",
104: "Fatal accident",
105: "Spark plugs",
106: "Fuel pipe",
107: "Eye injury",
108: "Oil pipe",
109: "Axle",
110: "Water pipe",
111: "+14 Laps",
112: "+15 Laps",
113: "+25 Laps",
114: "+18 Laps",
115: "+22 Laps",
116: "+16 Laps",
117: "+24 Laps",
118: "+29 Laps",
119: "+23 Laps",
120: "+21 Laps",
121: "Magneto",
122: "+44 Laps",
123: "+30 Laps",
124: "+19 Laps",
125: "+46 Laps",
126: "Supercharger",
127: "+20 Laps",
128: "+42 Laps",
129: "Engine misfire",
130: "Collision damage",
131: "Power Unit",
132: "ERS",
135: "Brake duct",
136: "Seat",
137: "Damage",
138: "Debris",
139: "Illness",
}

View File

@ -1,3 +1,5 @@
""" Ergast class """
from __future__ import annotations
from typing import Callable
@ -14,9 +16,21 @@ from ergast_py.requester import Requester
from ergast_py.type_constructor import TypeConstructor
#pylint: disable=too-many-public-methods
class Ergast():
"""
Class for querying the Ergast API
Ergast
~~~~~~
Class for querying the Ergast API.
Build up the queries using the available functions.
>>> e = ergast_py.Ergast()
>>> e.season(2021).round(1).driver_str("alonso")
Get the data using ``.get_xyz()`` functions.
>>> print(e.get_result())
"""
def __init__(self) -> None:
@ -26,6 +40,11 @@ class Ergast():
def reset(self) -> None:
"""
Reset the Ergast query building.
Should be called after a query is run to prevent forward interraction.
"""
self.params = {
"season": None,
"seasons": None,
@ -52,74 +71,167 @@ class Ergast():
#
def season(self, year: int="current") -> Ergast:
"""
Add a season to the current query
>>> e.season(2022).get_races()
"""
self.params["season"] = year
return self
def round(self, round_no: int="last") -> Ergast:
"""
Add a round to the current query
>>> e.season(1999).round(3).get_circuit()
"""
self.params["round"] = round_no
return self
def driver(self, driver: Driver) -> Ergast:
"""
Add a driver to the current query
>>> alonso = e.driver_str("alonso").get_driver()
>>> e.driver(alonso).get_results()
"""
self.params["driver"] = driver.driverId
return self
def driver_str(self, driver: str) -> Ergast:
"""
Add a driver to the current query
>>> e.driver_str("alonso").get_driver()
"""
self.params["driver"] = driver
return self
def constructor(self, constructor: Constructor) -> Ergast:
"""
Add a constructor to the current query
>>> mercedes = e.constructor_str("mercedes").get_constructor()
>>> e.constructor(mercedes).get_constructor_standings()
"""
self.params["constructor"] = constructor.constructorId
return self
def constructor_str(self, constructor: str) -> Ergast:
"""
Add a constructor to the current query
>>> e.constructor_str("mercedes").get_constructor()
"""
self.params["constructor"] = constructor
return self
def qualifying(self, position: int) -> Ergast:
"""
Add a qualifying position to the current query
>>> e.season(2021).qualifying(1).get_drivers()
"""
self.params["qualifying"] = position
return self
def sprint(self, position: int) -> Ergast:
"""
Add a sprint result to the current query
>>> e.season(2021).sprint(3).get_sprints()
"""
self.params["sprint"] = position
return self
def grid(self, position: int) -> Ergast:
"""
Add a starting grid position to the current query
>>> e.season(2021).round(1).grid(1).get_result()
"""
self.params["grid"] = position
return self
def result(self, position: int) -> Ergast:
"""
Add a final result to the current query
>>> e.season(2021).round(1).result(20).get_result()
"""
self.params["result"] = position
return self
def fastest(self, position: int) -> Ergast:
"""
Add a driver's fastest lap ranking to the current query
>>> e.season(2021).round(1).fastest(1).get_driver()
"""
self.params["fastest"] = position
return self
def circuit(self, circuit: Circuit) -> Ergast:
"""
Add a circuit to the current query
>>> silverstone = e.circuit_str("silverstone").get_circuit()
>>> e.circuit(silverstone)
"""
self.params["circuit"] = circuit.circuitId
return self
def circuit_str(self, circuit: str) -> Ergast:
"""
Add a circuit to the current query
>>> e.circuit_str("silverstone").get_circuit()
"""
self.params["circuit"] = circuit
return self
def status(self, status: int) -> Ergast:
"""
Add a finishing status to the current query
>>> e.driver_str("alonso").status(2)
"""
self.params["status"] = status
return self
def status_str(self, status: str) -> Ergast:
self.params["status"] = StatusType().status_map[status]
"""
Add a finishing status to the current query
>>> e.season(2021).round(1).status_str("Disqualified")
"""
self.params["status"] = StatusType().string_to_id[status]
return self
def standing(self, position: int) -> Ergast:
"""
Add a position in the standings to the current query
>>> e.standing(1).get_driver_standings()
"""
self.params["standing"] = position
return self
def lap(self, lap_number: int) -> Ergast:
"""
Add a certain lap to the current query
>>> e.season(2021).round(1).lap(1).get_laps()
"""
self.params["lap"] = lap_number
return self
def pit_stop(self, stop_number: int) -> Ergast:
"""
Add a certain pit stop to the current query
>>> e.season(2021).round(1).pit_stop(1).get_pit_stops()
"""
self.params["pit_stop"] = stop_number
return self
@ -128,10 +240,20 @@ class Ergast():
#
def limit(self, amount: int) -> Ergast:
"""
Limit the results in the current query
>>> e.season(2021).limit(2).get_drivers()
"""
self.params["limit"] = amount
return self
def offset(self, amount: int) -> Ergast:
"""
Offset the results in the current query
>>> e.season(2021).limit(2).offset(4).get_drivers()
"""
self.params["offset"] = amount
return self
@ -156,191 +278,187 @@ class Ergast():
# Race and Results Queries
def get_circuits(self) -> list[Circuit]:
return self._get_items(self.requester.get_circuits, self.type_constructor.construct_circuits)
"""
Get a list of circuits from the current query
"""
return self._get_items(self.requester.get_circuits,
self.type_constructor.construct_circuits)
def get_circuit(self) -> Circuit:
return self._get_item(self.requester.get_circuits, self.type_constructor.construct_circuits)
"""
Get a circuit from the current query
"""
return self._get_item(self.requester.get_circuits,
self.type_constructor.construct_circuits)
def get_constructors(self) -> list[Constructor]:
constructors_json = self.requester.get_constructors(self.params)
constructors = self.type_constructor.construct_constructors(constructors_json)
self.reset()
return constructors
"""
Get a list of constructors from the current query
"""
return self._get_items(self.requester.get_constructors,
self.type_constructor.construct_constructors)
def get_constructor(self) -> Constructor:
constructors_json = self.requester.get_constructors(self.params)
constructors = self.type_constructor.construct_constructors(constructors_json)
self.reset()
if len(constructors) == 1:
return constructors[0]
else:
raise Exception("More than 1 item found")
"""
Get a constructor from the current query
"""
return self._get_item(self.requester.get_constructors,
self.type_constructor.construct_constructors)
def get_drivers(self) -> list[Driver]:
drivers_json = self.requester.get_drivers(self.params)
drivers = self.type_constructor.construct_drivers(drivers_json)
self.reset()
return drivers
"""
Get a list of drivers from the current query
"""
return self._get_items(self.requester.get_drivers,
self.type_constructor.construct_drivers)
def get_driver(self) -> Driver:
drivers_json = self.requester.get_drivers(self.params)
drivers = self.type_constructor.construct_drivers(drivers_json)
self.reset()
if len(drivers) == 1:
return drivers[0]
else:
raise Exception("More than 1 item found")
"""
Get a driver from the current query
"""
return self._get_item(self.requester.get_drivers,
self.type_constructor.construct_drivers)
def get_qualifyings(self) -> list[Race]:
qualify_json = self.requester.get_qualifying(self.params)
qualifying = self.type_constructor.construct_races(qualify_json)
self.reset()
return qualifying
"""
Get a list of qualifyings from the current query
"""
return self._get_items(self.requester.get_qualifying,
self.type_constructor.construct_races)
def get_qualifying(self) -> Race:
qualify_json = self.requester.get_qualifying(self.params)
qualifying = self.type_constructor.construct_races(qualify_json)
self.reset()
if len(qualifying) == 1:
return qualifying[0]
else:
raise Exception("More than 1 item found")
"""
Get a qualifying from the current query
"""
return self._get_item(self.requester.get_qualifying,
self.type_constructor.construct_races)
def get_sprints(self) -> list[Race]:
sprint_json = self.requester.get_sprints(self.params)
sprint = self.type_constructor.construct_races(sprint_json)
self.reset()
return sprint
"""
Get a list of sprints from the current query
"""
return self._get_items(self.requester.get_sprints,
self.type_constructor.construct_races)
def get_sprint(self) -> Race:
sprint_json = self.requester.get_sprints(self.params)
sprint = self.type_constructor.construct_races(sprint_json)
self.reset()
if len(sprint) == 1:
return sprint[0]
else:
raise Exception("More than 1 item found")
"""
Get a sprint from the current query
"""
return self._get_item(self.requester.get_sprints,
self.type_constructor.construct_races)
def get_results(self) -> list[Race]:
results_json = self.requester.get_results(self.params)
results = self.type_constructor.construct_races(results_json)
self.reset()
return results
"""
Get a list of results from the current query
"""
return self._get_items(self.requester.get_results,
self.type_constructor.construct_races)
def get_result(self) -> Race:
results_json = self.requester.get_results(self.params)
results = self.type_constructor.construct_races(results_json)
self.reset()
if len(results) == 1:
return results[0]
else:
raise Exception("More than 1 item found")
"""
Get a result from the current query
"""
return self._get_item(self.requester.get_results,
self.type_constructor.construct_races)
def get_races(self) -> list[Race]:
races_json = self.requester.get_races(self.params)
races = self.type_constructor.construct_races(races_json)
self.reset()
return races
"""
Get a list of races from the current query
"""
return self._get_items(self.requester.get_races,
self.type_constructor.construct_races)
def get_race(self) -> Race:
races_json = self.requester.get_races(self.params)
races = self.type_constructor.construct_races(races_json)
self.reset()
if len(races) == 1:
return races[0]
else:
raise Exception("More than 1 item found")
"""
Get a race from the current query
"""
return self._get_item(self.requester.get_races,
self.type_constructor.construct_races)
def get_seasons(self) -> list[Season]:
seasons_json = self.requester.get_seasons(self.params)
seasons = self.type_constructor.construct_seasons(seasons_json)
self.reset()
return seasons
"""
Get a list of seasons from the current query
"""
return self._get_items(self.requester.get_seasons,
self.type_constructor.construct_seasons)
def get_season(self) -> Season:
seasons_json = self.requester.get_seasons(self.params)
seasons = self.type_constructor.construct_seasons(seasons_json)
self.reset()
if len(seasons) == 1:
return seasons[0]
else:
raise Exception("More than 1 item found")
"""
Get a season from the current query
"""
return self._get_item(self.requester.get_seasons,
self.type_constructor.construct_seasons)
def get_statuses(self) -> list[Status]:
statuses_json = self.requester.get_statuses(self.params)
statuses = self.type_constructor.construct_statuses(statuses_json)
self.reset()
return statuses
"""
Get a list of statuses from the current query
"""
return self._get_items(self.requester.get_statuses,
self.type_constructor.construct_statuses)
def get_status(self) -> Status:
statuses_json = self.requester.get_statuses(self.params)
statuses = self.type_constructor.construct_statuses(statuses_json)
self.reset()
if len(statuses) == 1:
return statuses[0]
else:
raise Exception("More than 1 item found")
"""
Get a status from the current query
"""
return self._get_item(self.requester.get_statuses,
self.type_constructor.construct_statuses)
# Standings Queries
def get_driver_standings(self) -> list[StandingsList]:
standings_lists_json = self.requester.get_driver_standings(self.params)
standings_lists = self.type_constructor.construct_standings_lists(standings_lists_json)
self.reset()
return standings_lists
"""
Get a list of driver standings from the current query
"""
return self._get_items(self.requester.get_driver_standings,
self.type_constructor.construct_driver_standings)
def get_driver_standing(self) -> StandingsList:
standings_lists_json = self.requester.get_driver_standings(self.params)
standings_lists = self.type_constructor.construct_standings_lists(standings_lists_json)
self.reset()
if len(standings_lists) == 1:
return standings_lists[0]
else:
raise Exception("More than 1 item found")
"""
Get a driver standing from the current query
"""
return self._get_item(self.requester.get_driver_standings,
self.type_constructor.construct_driver_standings)
def get_constructor_standings(self) -> list[StandingsList]:
standings_lists_json = self.requester.get_constructor_standings(self.params)
standings_lists = self.type_constructor.construct_standings_lists(standings_lists_json)
self.reset()
return standings_lists
"""
Get a list of constructor standings from the current query
"""
return self._get_items(self.requester.get_constructor_standings,
self.type_constructor.construct_constructor_standings)
def get_constructor_standing(self) -> StandingsList:
standings_lists_json = self.requester.get_constructor_standings(self.params)
standings_lists = self.type_constructor.construct_standings_lists(standings_lists_json)
self.reset()
if len(standings_lists) == 1:
return standings_lists[0]
else:
raise Exception("More than 1 item found")
"""
Get a constructor standing from the current query
"""
return self._get_item(self.requester.get_constructor_standings,
self.type_constructor.construct_constructor_standings)
# Laps and Pit Stops Queries
def get_laps(self) -> list[Race]:
laps_json = self.requester.get_laps(self.params)
laps = self.type_constructor.construct_races(laps_json)
self.reset()
return laps
"""
Get a list of laps from the current query
"""
return self._get_items(self.requester.get_laps,
self.type_constructor.construct_races)
def get_lap(self) -> Race:
laps_json = self.requester.get_laps(self.params)
laps = self.type_constructor.construct_races(laps_json)
self.reset()
if len(laps) == 1:
return laps[0]
else:
raise Exception("More than 1 item found")
"""
Get a lap from the current query
"""
return self._get_item(self.requester.get_laps,
self.type_constructor.construct_races)
def get_pit_stops(self) -> list[Race]:
pit_stops_json = self.requester.get_pit_stops(self.params)
pit_stops = self.type_constructor.construct_races(pit_stops_json)
self.reset()
return pit_stops
"""
Get a list of pit stops from the current query
"""
return self._get_items(self.requester.get_pit_stops,
self.type_constructor.construct_races)
def get_pit_stop(self) -> Race:
pit_stops_json = self.requester.get_pit_stops(self.params)
pit_stops = self.type_constructor.construct_races(pit_stops_json)
self.reset()
if len(pit_stops) == 1:
return pit_stops[0]
else:
raise Exception("More than 1 item found")
"""
Get a pit stop from the current query
"""
return self._get_item(self.requester.get_pit_stops,
self.type_constructor.construct_races)

View File

@ -1,44 +1,84 @@
""" Helpers class """
import datetime
class Helpers:
"""
Helpers for the construction of models
"""
def construct_datetime_str(self, date: str, time: str) -> datetime.datetime:
"""
Construct a datetime.datetime from the date and time strings.
Looking for the format of ``%Y-%m-%d %H:%M:%SZ``
"""
new_datetime = datetime.datetime.strptime(f"{date} {time}", "%Y-%m-%d %H:%M:%SZ")
new_datetime = new_datetime.replace(tzinfo=datetime.timezone.utc)
return new_datetime
def construct_datetime_dict(self, dict: dict) -> datetime.datetime:
if "date" not in dict or "time" not in dict:
def construct_datetime_dict(self, datetime_dict: dict) -> datetime.datetime:
"""
Construct a datetime.datetime from a dictionary.
Dictionary should contain the keys "date" and "time"
"""
if "date" not in datetime_dict or "time" not in datetime_dict:
return None
return self.construct_datetime_str(dict["date"], dict["time"])
return self.construct_datetime_str(datetime_dict["date"], datetime_dict["time"])
def construct_date(self, date: str) -> datetime.date:
"""
Construct a datetime.date from a date string
"""
elements = date.split("-")
return datetime.date(year=int(elements[0]), month=int(elements[1]), day=int(elements[2]))
def construct_lap_time_millis(self, millis: dict) -> datetime.time:
"""
Construct a datetime.time (lap time) from a dict containing the millis
"""
if "millis" in millis:
value = int(millis["millis"])
return datetime.datetime.fromtimestamp(value/1000.0).time()
return None
def format_lap_time(self, time: str) -> datetime.time:
"""
Construct a datetime.time (lap time) from a time string
"""
if time != "":
return datetime.datetime.strptime(time, "%M:%S.%f").time()
return None
def construct_lap_time(self, time: dict) -> datetime.time:
"""
Construct a datetime.time (lap time) from a time dictionary
The dictionary should contain the key "time"
"""
if "time" in time:
value = time["time"]
return self.format_lap_time(value)
return None
def construct_local_time(self, time: str) -> datetime.time:
if "time" != "":
"""
Construct a datetime.time from a time string
Looking for the format of ``%H:%M:%S``
"""
if time != "":
return datetime.datetime.strptime(f"{time}", "%H:%M:%S").time()
return None
def construct_pitstop_duration(self, time: str) -> datetime.time:
if "time" != "":
"""
Construct a datetime.time (pit stop duration) from a time string
Looking for the format of ``%S.%f``
"""
if time != "":
return datetime.datetime.strptime(f"{time}", "%S.%f").time()
return None

View File

@ -1,9 +1,15 @@
""" AverageSpeed class """
from dataclasses import dataclass
from ergast_py.models.model import Model
@dataclass
class AverageSpeed:
class AverageSpeed(Model):
"""
Representation of a Drivers Average Speed
Average Speeds may contain:
units: String
speed: Float
@ -12,12 +18,3 @@ class AverageSpeed:
def __init__(self, units: str, speed: float) -> None:
self.units = units
self.speed = speed
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,28 +1,25 @@
""" Circuit class """
from dataclasses import dataclass
from ergast_py.models.location import Location
from ergast_py.models.model import Model
@dataclass
class Circuit:
class Circuit(Model):
"""
Representation of a Formula One Circuit
Circuits may contain:
circuitId: String
circuit_id: String
url: String
circuitName: String
circuit_name: String
location: Location
"""
def __init__(self, circuitId: str, url: str, circuitName: str, location: Location) -> None:
self.circuitId = circuitId
def __init__(self, circuit_id: str, url: str, circuit_name: str, location: Location) -> None:
self.circuit_id = circuit_id
self.url = url
self.circuitName = circuitName
self.circuit_name = circuit_name
self.location = location
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,27 +1,24 @@
""" Constructor class """
from dataclasses import dataclass
from ergast_py.models.model import Model
@dataclass
class Constructor:
class Constructor(Model):
"""
Representation of a Formula One Team
Constructors may contain:
constructorId: String
constructor_id: String
url: String
name: String
nationality: String
"""
def __init__(self, constructorId: str, url: str, name: str, nationality: str) -> None:
self.constructorId = constructorId
def __init__(self, constructor_id: str, url: str, name: str, nationality: str) -> None:
self.constructor_id = constructor_id
self.url = url
self.name = name
self.nationality = nationality
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,31 +1,28 @@
""" ConstructorStanding class """
from dataclasses import dataclass
from ergast_py.models.constructor import Constructor
from ergast_py.models.model import Model
@dataclass
class ConstructorStanding:
class ConstructorStanding(Model):
"""
Representation of a Formula One Constructor's standing in a Season
Constructor Standings may contain:
position: Integer
positionText: String
position_text: String
points: Float
wins: Integer
constructor: Constructor
"""
def __init__(self, position: int, positionText: str, points: float, wins: int, constructor: Constructor) -> None:
def __init__(self, position: int, position_text: str, points: float, wins: int, #pylint: disable=too-many-arguments
constructor: Constructor) -> None:
self.position = position
self.positionText = positionText
self.position_text = position_text
self.points = points
self.wins = wins
self.constructor = constructor
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,38 +1,34 @@
from dataclasses import dataclass
from ergast_py.helpers import Helpers
""" Driver class """
import datetime
from dataclasses import dataclass
from ergast_py.models.model import Model
@dataclass
class Driver:
class Driver(Model):
"""
Representation of a Formula One driver
Drivers may contain:
driverId: String
permanentNumber: Integer
driver_id: String
permanent_number: Integer
code: String
url: String
givenName: String
familyName: String
dateOfBirth: datetime.date
given_name: String
family_name: String
date_of_birth: datetime.date
nationality: String
"""
def __init__(self, driverId: str, code: str, url: str, givenName: str, familyName: str, dateOfBirth: datetime.date,
nationality: str, permanentNumber: int) -> None:
self.driverId = driverId
self.permanentNumber = permanentNumber
def __init__(self, driver_id: str, code: str, url: str, given_name: str, family_name: str,
date_of_birth: datetime.date, nationality: str, permanent_number: int) -> None:
self.driver_id = driver_id
self.permanent_number = permanent_number
self.code = code
self.url = url
self.givenName = givenName
self.familyName = familyName
self.dateOfBirth = dateOfBirth
self.given_name = given_name
self.family_name = family_name
self.date_of_birth = date_of_birth
self.nationality = nationality
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,35 +1,31 @@
from dataclasses import dataclass
from ergast_py.models.constructor import Constructor
""" DriverStanding class """
from dataclasses import dataclass
from ergast_py.models.constructor import Constructor
from ergast_py.models.driver import Driver
from ergast_py.models.model import Model
@dataclass
class DriverStanding:
class DriverStanding(Model):
"""
Representation of a Formula One Driver's standing in a Season
Driver Standings may contain:
position: Integer
positionText: String
position_text: String
points: Float
wins: Integer
driver: Driver
constructors: Constructor[]
"""
def __init__(self, position: int, positionText: str, points: float, wins: int, driver: Driver,
def __init__(self, position: int, position_text: str, points: float, wins: int, driver: Driver, #pylint: disable=too-many-arguments
constructors: list[Constructor]) -> None:
self.position = position
self.positionText = positionText
self.position_text = position_text
self.points = points
self.wins = wins
self.driver = driver
self.constructors = constructors
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,29 +1,27 @@
from dataclasses import dataclass
from ergast_py.models.average_speed import AverageSpeed
""" FastestLap class """
import datetime
from dataclasses import dataclass
from ergast_py.models.average_speed import AverageSpeed
from ergast_py.models.model import Model
@dataclass
class FastestLap:
class FastestLap(Model):
"""
Representation of a Fastest Lap for a Formula One Driver
Fastest Laps may contain:
rank: Integer
lap: Integer
time: datetime.time
averageSpeed: AverageSpeed
average_speed: AverageSpeed
"""
def __init__(self, rank: int, lap: int, time: datetime.time, averageSpeed: AverageSpeed) -> None:
def __init__(self, rank: int, lap: int, time: datetime.time,
average_speed: AverageSpeed) -> None:
self.rank = rank
self.lap = lap
self.time = time
self.averageSpeed = averageSpeed
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
self.average_speed = average_speed

View File

@ -1,11 +1,16 @@
""" Lap class """
from dataclasses import dataclass
from ergast_py.models.model import Model
from ergast_py.models.timing import Timing
@dataclass
class Lap:
class Lap(Model):
"""
Representation of a single Lap from a Formula One race
Laps may contain:
number: Integer
timings: Timing[]
@ -14,12 +19,3 @@ class Lap:
def __init__(self, number: int, timings: list[Timing]) -> None:
self.number = number
self.timings = timings
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,9 +1,15 @@
""" Location class """
from dataclasses import dataclass
from ergast_py.models.model import Model
@dataclass
class Location:
class Location(Model):
"""
Representation of a Location for a Formula One Circuit
Locations may contain:
lat: Float
long: Float
@ -16,12 +22,3 @@ class Location:
self.longitude = longitude
self.locality = locality
self.country = country
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

14
ergast_py/models/model.py Normal file
View File

@ -0,0 +1,14 @@
""" Model class """
class Model():
"""
Base class for Models within Ergast-py
"""
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,31 +1,28 @@
from dataclasses import dataclass
""" PitStop class """
import datetime
from dataclasses import dataclass
from ergast_py.models.model import Model
@dataclass
class PitStop:
class PitStop(Model):
"""
Representation of a single Pit Stop from a Formula One race
PitStops may contain:
driverId: String
driver_id: String
lap: Integer
stop: Integer
localTime: datetime.datetime
local_time: datetime.datetime
duration: datetime.time
"""
def __init__(self, driverId: str, lap: int, stop: int, localTime: datetime.datetime,
def __init__(self, driver_id: str, lap: int, stop: int, local_time: datetime.datetime,
duration: datetime.time) -> None:
self.driverId = driverId
self.driver_id = driver_id
self.lap = lap
self.stop = stop
self.localTime = localTime
self.local_time = local_time
self.duration = duration
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,62 +1,58 @@
from dataclasses import dataclass
import datetime
""" Race class """
import datetime
from dataclasses import dataclass
from ergast_py.helpers import Helpers
from ergast_py.models.circuit import Circuit
from ergast_py.models.lap import Lap
from ergast_py.models.result import Result
from ergast_py.models.model import Model
from ergast_py.models.pit_stop import PitStop
from ergast_py.models.result import Result
@dataclass
class Race:
class Race(Model):
"""
Representation of a single Race from a Formula One season
Races may contain:
season: Integer
round: Integer
round_no: Integer
url: String
raceName: String
race_name: String
circuit: Circuit
date: datetime.datetime
results: Result[]
firstPractice: datetime.datetime
secondPractice: datetime.datetime
thirdPractice: datetime.datetime
first_practice: datetime.datetime
second_practice: datetime.datetime
third_practice: datetime.datetime
sprint: datetime.datetime
sprintResults: Result[]
sprint_results: Result[]
qualifying: datetime.datetime
qualifyingResults: Result[]
pitStops: PitStop[]
qualifying_results: Result[]
pit_stops: PitStop[]
laps: Lap[]
"""
def __init__(self, season: int, round: int, url: str, raceName: str, circuit: Circuit, date: datetime.datetime,
results: list[Result], firstPractice: datetime.datetime, secondPractice: datetime.datetime,
thirdPractice: datetime.datetime, sprint: datetime.datetime, sprintResults: list[Result],
qualifying: datetime.datetime, qualifyingResults: list[Result], pitStops: list[PitStop],
laps: list[Lap]) -> None:
def __init__(self, season: int, round_no: int, url: str, race_name: str, circuit: Circuit,
date: datetime.datetime, results: list[Result], first_practice: datetime.datetime,
second_practice: datetime.datetime, third_practice: datetime.datetime,
sprint: datetime.datetime, sprint_results: list[Result],
qualifying: datetime.datetime, qualifying_results: list[Result],
pit_stops: list[PitStop], laps: list[Lap]) -> None:
self.season = season
self.round = round
self.round_no = round_no
self.url = url
self.raceName = raceName
self.race_name = race_name
self.circuit = circuit
self.date = date
self.results = results
self.firstPractice = firstPractice
self.secondPractice = secondPractice
self.thirdPractice = thirdPractice
self.first_practice = first_practice
self.second_practice = second_practice
self.third_practice = third_practice
self.sprint = sprint
self.sprintResults = sprintResults
self.sprint_results = sprint_results
self.qualifying = qualifying
self.qualifyingResults = qualifyingResults
self.pitStops = pitStops
self.qualifying_results = qualifying_results
self.pit_stops = pit_stops
self.laps = laps
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,18 +1,23 @@
from dataclasses import dataclass
import datetime
from ergast_py.models.constructor import Constructor
""" Result class """
import datetime
from dataclasses import dataclass
from ergast_py.models.constructor import Constructor
from ergast_py.models.driver import Driver
from ergast_py.models.fastest_lap import FastestLap
from ergast_py.models.model import Model
@dataclass
class Result:
class Result(Model):
"""
Representation of a single Result from a Formula One race
Results may contain:
number: Integer
position: Integer
positionText: String
position_text: String
points: Integer
driver: Driver
constructor: Constructor
@ -20,18 +25,19 @@ class Result:
laps: Integer
status: Integer
time: datetime.time
fastestLap: FastestLap
q1: datetime.time
q2: datetime.time
q3: datetime.time
fastest_lap: FastestLap
qual_1: datetime.time
qual_2: datetime.time
qual_3: datetime.time
"""
def __init__(self, number: int, position: int, positionText: str, points: float, driver: Driver,
constructor: Constructor, grid: int, laps: int, status: int, time: datetime.time,
fastestLap: FastestLap, q1: datetime.time, q2: datetime.time, q3: datetime.time) -> None:
def __init__(self, number: int, position: int, position_text: str, points: float,
driver: Driver, constructor: Constructor, grid: int, laps: int, status: int,
time: datetime.time, fastest_lap: FastestLap, qual_1: datetime.time,
qual_2: datetime.time, qual_3: datetime.time) -> None:
self.number = number
self.position = position
self.positionText = positionText
self.position_text = position_text
self.points = points
self.driver = driver
self.constructor = constructor
@ -39,16 +45,7 @@ class Result:
self.laps = laps
self.status = status
self.time = time
self.fastestLap = fastestLap
self.q1 = q1
self.q2 = q2
self.q3 = q3
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
self.fastest_lap = fastest_lap
self.qual_1 = qual_1
self.qual_2 = qual_2
self.qual_3 = qual_3

View File

@ -1,9 +1,15 @@
""" Season class """
from dataclasses import dataclass
from ergast_py.models.model import Model
@dataclass
class Season:
class Season(Model):
"""
Representation of a single Season in Formula One
Seasons may contain:
season: Integer
url: String
@ -12,12 +18,3 @@ class Season:
def __init__(self, season: int, url: str) -> None:
self.season = season
self.url = url
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,30 +1,27 @@
""" StandingsList class """
from dataclasses import dataclass
from ergast_py.models.driver_standing import DriverStanding
from ergast_py.models.constructor_standing import ConstructorStanding
from ergast_py.models.driver_standing import DriverStanding
from ergast_py.models.model import Model
@dataclass
class StandingsList:
class StandingsList(Model):
"""
Representation of a set of Standings from a time in Formula One
StandingsLists may contain:
season: Integer
round: Integer
driverStandings: DriverStanding[]
constructorStandings: ConstructorStanding[]
round_no: Integer
driver_standings: DriverStanding[]
constructor_standings: ConstructorStanding[]
"""
def __init__(self, season: int, round: int, driverStandings: list[DriverStanding],
constructorStandings: list[ConstructorStanding]) -> None:
def __init__(self, season: int, round_no: int, driver_standings: list[DriverStanding],
constructor_standings: list[ConstructorStanding]) -> None:
self.season = season
self.round = round
self.driverStandings = driverStandings
self.constructorStandings = constructorStandings
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
self.round_no = round_no
self.driver_standings = driver_standings
self.constructor_standings = constructor_standings

View File

@ -1,25 +1,22 @@
""" Status class """
from dataclasses import dataclass
from ergast_py.models.model import Model
@dataclass
class Status:
class Status(Model):
"""
Representation of the finishing status of a Driver in a Race
Statuses may contain:
statusId: Integer
status_id: Integer
count: Integer
status: String
"""
def __init__(self, statusId: int, count: int, status: str) -> None:
self.statusId = statusId
def __init__(self, status_id: int, count: int, status: str) -> None:
self.status_id = status_id
self.count = count
self.status = status
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,26 +1,22 @@
from dataclasses import dataclass
""" Timing class """
import datetime
from dataclasses import dataclass
from ergast_py.models.model import Model
@dataclass
class Timing:
class Timing(Model):
"""
Representation of a single timing from a lap in Formula One
Timings may contain:
driverId: String
driver_id: String
position: Integer
time: datetime.time
"""
def __init__(self, driverId: str, position: int, time: datetime.time) -> None:
self.driverId = driverId
def __init__(self, driver_id: str, position: int, time: datetime.time) -> None:
self.driver_id = driver_id
self.position = position
self.time = time
pass
def __str__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"
def __repr__(self) -> str:
members = ', '.join(f"{key}={value}" for key, value in self.__dict__.items())
return f"{type(self).__name__}({members})"

View File

@ -1,6 +1,8 @@
import json
import requests
""" Requester class """
import json
import requests
from uritemplate import URITemplate
HOST = 'https://ergast.com/api'
@ -11,12 +13,7 @@ class Requester():
Perform requests to the Ergast API
"""
def __init__(self) -> None:
pass
def _get_race_results_params(self, param: dict) -> dict:
""" Acquire only the appropriate filters for Race/Results data """
return {
"season": param["season"],
"round": param["round"],
@ -40,10 +37,9 @@ class Requester():
}
def _get_race_results_criteria(self, params: dict, resource: str) -> dict:
""" Split the data into criteria and resource for Race/Results """
criteria = []
for key, value in params["filters"].items():
if (key != resource and value != None):
if (key != resource and value is not None):
criteria.append(key)
criteria.append(value)
@ -56,7 +52,6 @@ class Requester():
}
def _get_standings_params(self, param: dict) -> dict:
""" Acquire only the appropriate filters for Standings data """
return {
"season": param["season"],
"round": param["round"],
@ -72,10 +67,9 @@ class Requester():
}
def _get_standings_criteria(self, params: dict, resource: str) -> dict:
""" Split the data into criteria and resource for standings """
criteria = []
for key, value in params["filters"].items():
if (key != "standing" and value != None):
if (key != "standing" and value is not None):
criteria.append(key)
criteria.append(value)
@ -88,7 +82,6 @@ class Requester():
}
def _get_laps_pit_stops_params(self, param: dict) -> dict:
""" Acquire only the appropriate filters for Laps and Pit Stops data """
return {
"season": param["season"],
"round": param["round"],
@ -104,10 +97,9 @@ class Requester():
}
def _get_laps_pit_stops_criteria(self, params: dict, resource: str) -> dict:
""" Split the data into criteria and resource for Laps and Pit Stops """
criteria = []
for key, value in params["filters"].items():
if (key != resource and value != None):
if (key != resource and value is not None):
criteria.append(key)
criteria.append(value)
@ -120,19 +112,21 @@ class Requester():
}
def run_request(self, season, round, criteria, resource, value=None, limit=None, offset=None) -> dict:
""" Takes values to run the request and return a dict """
def run_request(self, season, round_no, criteria, resource, value=None, limit=None,
offset=None) -> dict:
"""
Takes values to run the request and return a dict
"""
url_tmpl = URITemplate('https://ergast.com/api{/series}{/season}{/round}'
'{/criteria*}{/resource}{/value}.json{?limit,offset}')
url = url_tmpl.expand(host=HOST, series=SERIES,
season=season, round=round,
season=season, round=round_no,
criteria=criteria, resource=resource,
value=value, limit=limit, offset=offset)
response = requests.get(url)
if response.status_code == 200:
return json.loads(response.text)
else:
raise Exception(f"Failed with status code {response.status_code}. Error: {response.reason}")
#
@ -140,142 +134,194 @@ class Requester():
#
def get_circuits(self, param: dict) -> dict:
"""
Get the Circuits JSON from the Ergast API
"""
params = self._get_race_results_params(param)
filters = self._get_race_results_criteria(params, "circuits")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["CircuitTable"]["Circuits"]
return api_json["MRData"]["CircuitTable"]["Circuits"]
def get_constructors(self, param: dict) -> dict:
"""
Get the Constructors JSON from the Ergast API
"""
params = self._get_race_results_params(param)
filters = self._get_race_results_criteria(params, "constructors")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["ConstructorTable"]["Constructors"]
return api_json["MRData"]["ConstructorTable"]["Constructors"]
def get_drivers(self, param: dict) -> dict:
"""
Get the Drivers JSON from the Ergast API
"""
params = self._get_race_results_params(param)
filters = self._get_race_results_criteria(params, "drivers")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["DriverTable"]["Drivers"]
return api_json["MRData"]["DriverTable"]["Drivers"]
def get_qualifying(self, param: dict) -> dict:
"""
Get the Qualifying JSON from the Ergast API
"""
params = self._get_race_results_params(param)
filters = self._get_race_results_criteria(params, "qualifying")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["RaceTable"]["Races"]
return api_json["MRData"]["RaceTable"]["Races"]
def get_sprints(self, param: dict) -> dict:
"""
Get the Sprints JSON from the Ergast API
"""
params = self._get_race_results_params(param)
filters = self._get_race_results_criteria(params, "sprint")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["RaceTable"]["Races"]
return api_json["MRData"]["RaceTable"]["Races"]
def get_results(self, param: dict) -> dict:
"""
Get the Results JSON from the Ergast API
"""
params = self._get_race_results_params(param)
filters = self._get_race_results_criteria(params, "results")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["RaceTable"]["Races"]
return api_json["MRData"]["RaceTable"]["Races"]
def get_races(self, param: dict) -> dict:
"""
Get the Races JSON from the Ergast API
"""
params = self._get_race_results_params(param)
filters = self._get_race_results_criteria(params, "races")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["RaceTable"]["Races"]
return api_json["MRData"]["RaceTable"]["Races"]
def get_seasons(self, param: dict) -> dict:
"""
Get the Seasons JSON from the Ergast API
"""
params = self._get_race_results_params(param)
filters = self._get_race_results_criteria(params, "seasons")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["SeasonTable"]["Seasons"]
return api_json["MRData"]["SeasonTable"]["Seasons"]
def get_statuses(self, param: dict) -> dict:
"""
Get the Statuses JSON from the Ergast API
"""
params = self._get_race_results_params(param)
filters = self._get_race_results_criteria(params, "status")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["StatusTable"]["Status"]
return api_json["MRData"]["StatusTable"]["Status"]
#
# Standings
#
def get_driver_standings(self, param: dict) -> dict:
"""
Get the Driver Standings JSON from the Ergast API
"""
params = self._get_standings_params(param)
filters = self._get_standings_criteria(params, "driverStandings")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["StandingsTable"]["StandingsLists"]
return api_json["MRData"]["StandingsTable"]["StandingsLists"]
def get_constructor_standings(self, param: dict) -> dict:
"""
Get the Constructor Standings JSON from the Ergast API
"""
params = self._get_standings_params(param)
filters = self._get_standings_criteria(params, "constructorStandings")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["StandingsTable"]["StandingsLists"]
return api_json["MRData"]["StandingsTable"]["StandingsLists"]
#
# Laps and Pit Stops
#
def get_laps(self, param: dict) -> dict:
"""
Get the Laps JSON from the Ergast API
"""
params = self._get_laps_pit_stops_params(param)
filters = self._get_laps_pit_stops_criteria(params, "laps")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["RaceTable"]["Races"]
return api_json["MRData"]["RaceTable"]["Races"]
def get_pit_stops(self, param: dict) -> dict:
"""
Get the Pit Stops JSON from the Ergast API
"""
params = self._get_laps_pit_stops_params(param)
filters = self._get_laps_pit_stops_criteria(params, "pitstops")
json = self.run_request(season=params["season"], round=params["round"],
criteria=filters["criteria"], resource=filters["resource"], value=filters["value"],
limit=params["paging"]["limit"], offset=params["paging"]["offset"])
api_json = self.run_request(season=params["season"], round_no=params["round"],
criteria=filters["criteria"], resource=filters["resource"],
value=filters["value"], limit=params["paging"]["limit"],
offset=params["paging"]["offset"])
return json["MRData"]["RaceTable"]["Races"]
return api_json["MRData"]["RaceTable"]["Races"]

View File

@ -1,23 +1,27 @@
""" TypeConstructor class """
from ergast_py.constants.expected import Expected
from ergast_py.constants.status_type import StatusType
from ergast_py.helpers import Helpers
from ergast_py.models.average_speed import AverageSpeed
from ergast_py.models.circuit import Circuit
from ergast_py.models.constructor import Constructor
from ergast_py.models.constructor_standing import ConstructorStanding
from ergast_py.models.driver import Driver
from ergast_py.models.driver_standing import DriverStanding
from ergast_py.models.fastest_lap import FastestLap
from ergast_py.models.lap import Lap
from ergast_py.models.location import Location
from ergast_py.models.circuit import Circuit
from ergast_py.models.constructor import Constructor
from ergast_py.models.pit_stop import PitStop
from ergast_py.models.race import Race
from ergast_py.models.result import Result
from ergast_py.helpers import Helpers
from ergast_py.constants.status_type import StatusType
from ergast_py.models.season import Season
from ergast_py.models.standings_list import StandingsList
from ergast_py.models.status import Status
from ergast_py.models.timing import Timing
from ergast_py.constants.expected import Expected
#pylint: disable=too-many-public-methods
class TypeConstructor():
"""
Class for constructing types out of dicts
@ -96,6 +100,9 @@ class TypeConstructor():
#
def construct_location(self, location: dict) -> Location:
"""
Construct a Location from a JSON dictionary
"""
location = self._populate_missing_location(location=location)
return Location(
latitude=float(location["lat"]),
@ -105,101 +112,137 @@ class TypeConstructor():
)
def construct_circuit(self, circuit: dict) -> Circuit:
"""
Construct a Circuit from a JSON dictionary
"""
circuit = self._populate_missing_circuit(circuit)
return Circuit(
circuitId=circuit["circuitId"],
circuit_id=circuit["circuitId"],
url=circuit["url"],
circuitName=circuit["circuitName"],
circuit_name=circuit["circuitName"],
location=self.construct_location(circuit["Location"])
)
def construct_circuits(self, circuits: dict) -> list[Circuit]:
"""
Construct a list of Circuits from a JSON dictionary
"""
return [self.construct_circuit(circuit) for circuit in circuits]
def construct_constructor(self, constructor: dict) -> Constructor:
"""
Construct a Constructor from a JSON dictionary
"""
constructor = self._populate_missing_constructor(constructor)
return Constructor(
constructorId=constructor["constructorId"],
constructor_id=constructor["constructorId"],
url=constructor["url"],
name=constructor["name"],
nationality=constructor["nationality"]
)
def construct_constructors(self, constructors: dict) -> list[Constructor]:
"""
Construct a list of Constructors from a JSON dictionary
"""
return [self.construct_constructor(constructor) for constructor in constructors]
def construct_driver(self, driver: dict) -> Driver:
"""
Construct a Driver from a JSON dictionary
"""
driver = self._populate_missing_driver(driver)
return Driver(
driverId=driver["driverId"],
permanentNumber=int(driver["permanentNumber"]),
driver_id=driver["driverId"],
permanent_number=int(driver["permanentNumber"]),
code=driver["code"],
url=driver["url"],
givenName=driver["givenName"],
familyName=driver["familyName"],
dateOfBirth=Helpers().construct_date(driver["dateOfBirth"]),
given_name=driver["givenName"],
family_name=driver["familyName"],
date_of_birth=Helpers().construct_date(driver["dateOfBirth"]),
nationality=driver["nationality"]
)
def construct_drivers(self, drivers: dict) -> list[Driver]:
"""
Construct a list of Drivers from a JSON dictionary
"""
return [self.construct_driver(driver) for driver in drivers]
def construct_race(self, race: dict) -> Race:
"""
Construct a Race from a JSON dictionary
"""
race = self._populate_missing_race(race)
return Race(
season=int(race["season"]),
round=int(race["round"]),
round_no=int(race["round"]),
url=race["url"],
raceName=race["raceName"],
race_name=race["raceName"],
circuit=self.construct_circuit(race["Circuit"]),
date=Helpers().construct_datetime_str(date=race["date"], time=race["time"]),
results=self.construct_results(race["Results"]),
firstPractice=Helpers().construct_datetime_dict(race["FirstPractice"]),
secondPractice=Helpers().construct_datetime_dict(race["SecondPractice"]),
thirdPractice=Helpers().construct_datetime_dict(race["ThirdPractice"]),
first_practice=Helpers().construct_datetime_dict(race["FirstPractice"]),
second_practice=Helpers().construct_datetime_dict(race["SecondPractice"]),
third_practice=Helpers().construct_datetime_dict(race["ThirdPractice"]),
sprint=Helpers().construct_datetime_dict(race["Sprint"]),
sprintResults=self.construct_results(race["SprintResults"]),
sprint_results=self.construct_results(race["SprintResults"]),
qualifying=Helpers().construct_datetime_dict(race["Qualifying"]),
qualifyingResults=self.construct_results(race["QualifyingResults"]),
pitStops=self.construct_pit_stops(race["PitStops"]),
qualifying_results=self.construct_results(race["QualifyingResults"]),
pit_stops=self.construct_pit_stops(race["PitStops"]),
laps=self.construct_laps(race["Laps"])
)
def construct_races(self, races: dict) -> list[Race]:
"""
Construct a list of Races from a JSON dictionary
"""
return [self.construct_race(race) for race in races]
def construct_result(self, result: dict) -> Result:
"""
Construct a Result from a JSON dictionary
"""
result = self._populate_missing_result(result)
return Result(
number=int(result["number"]),
position=int(result["position"]),
positionText=result["positionText"],
position_text=result["positionText"],
points=float(result["points"]),
driver=self.construct_driver(result["Driver"]),
constructor=self.construct_constructor(result["Constructor"]),
grid=int(result["grid"]),
laps=int(result["laps"]),
status=int(StatusType().status_map[result["status"]]),
status=int(StatusType().string_to_id[result["status"]]),
time=Helpers().construct_lap_time_millis(millis=result["Time"]),
fastestLap=self.construct_fastest_lap(result["FastestLap"]),
q1=Helpers().format_lap_time(time=result["Q1"]),
q2=Helpers().format_lap_time(time=result["Q2"]),
q3=Helpers().format_lap_time(time=result["Q3"]),
fastest_lap=self.construct_fastest_lap(result["FastestLap"]),
qual_1=Helpers().format_lap_time(time=result["Q1"]),
qual_2=Helpers().format_lap_time(time=result["Q2"]),
qual_3=Helpers().format_lap_time(time=result["Q3"]),
)
def construct_results(self, results: dict) -> list[Result]:
"""
Construct a list of Results from a JSON dictionary
"""
return [self.construct_result(result) for result in results]
def construct_fastest_lap(self, fastest_lap: dict) -> FastestLap:
"""
Construct a FastestLap from a JSON dictionary
"""
fastest_lap = self._populate_missing_fastest_lap(fastest_lap)
return FastestLap(
rank=int(fastest_lap["rank"]),
lap=int(fastest_lap["lap"]),
time=Helpers().construct_lap_time(time=fastest_lap["Time"]),
averageSpeed=self.construct_average_speed(fastest_lap["AverageSpeed"])
average_speed=self.construct_average_speed(fastest_lap["AverageSpeed"])
)
def construct_average_speed(self, average_speed: dict) -> AverageSpeed:
"""
Construct an AverageSpeed from a JSON dictionary
"""
average_speed = self._populate_missing_average_speed(average_speed)
return AverageSpeed(
units=average_speed["units"],
@ -207,19 +250,28 @@ class TypeConstructor():
)
def construct_pit_stop(self, pit_stop: dict) -> PitStop:
"""
Construct a PitStop from a JSON dictionary
"""
pit_stop = self._populate_missing_pit_stop(pit_stop)
return PitStop(
driverId=pit_stop["driverId"],
driver_id=pit_stop["driverId"],
lap=int(pit_stop["lap"]),
stop=int(pit_stop["stop"]),
localTime=Helpers().construct_local_time(pit_stop["time"]),
local_time=Helpers().construct_local_time(pit_stop["time"]),
duration=Helpers().construct_pitstop_duration(pit_stop["duration"])
)
def construct_pit_stops(self, pit_stops: dict) -> list[PitStop]:
"""
Construct a list of PitStops from a JSON dictionary
"""
return [self.construct_pit_stop(pit_stop) for pit_stop in pit_stops]
def construct_lap(self, lap: dict) -> Lap:
"""
Construct a Lap from a JSON dictionary
"""
lap = self._populate_missing_lap(lap)
return Lap(
number=int(lap["number"]),
@ -227,20 +279,32 @@ class TypeConstructor():
)
def construct_laps(self, laps: dict) -> list[Lap]:
"""
Construct a list of Laps from a JSON dictionary
"""
return [self.construct_lap(lap) for lap in laps]
def construct_timing(self, timing: dict) -> Timing:
"""
Construct a Timing from a JSON dictionary
"""
timing = self._populate_missing_timing(timing)
return Timing(
driverId=timing["driverId"],
driver_id=timing["driverId"],
position=int(timing["position"]),
time=Helpers().format_lap_time(time=timing["time"])
)
def construct_timings(self, timings: dict) -> list[Timing]:
"""
Construct a list of Timings from a JSON dictionary
"""
return [self.construct_timing(timing) for timing in timings]
def construct_season(self, season: dict) -> Season:
"""
Construct a Season from a JSON dictionary
"""
season = self._populate_missing_season(season)
return Season(
season=int(season["season"]),
@ -248,24 +312,36 @@ class TypeConstructor():
)
def construct_seasons(self, seasons: dict) -> list[Season]:
"""
Construct a list of Seasons from a JSON dictionary
"""
return [self.construct_season(season) for season in seasons]
def construct_status(self, status: dict) -> Status:
"""
Construct a Status from a JSON dictionary
"""
status = self._populate_missing_status(status)
return Status(
statusId=int(status["statusId"]),
status_id=int(status["statusId"]),
count=int(status["count"]),
status=status["status"]
)
def construct_statuses(self, statuses: dict) -> list[Season]:
def construct_statuses(self, statuses: dict) -> list[Status]:
"""
Construct a list of Statuses from a JSON dictionary
"""
return [self.construct_status(status) for status in statuses]
def construct_driver_standing(self, standing: dict) -> DriverStanding:
"""
Construct a DriverStanding from a JSON dictionary
"""
standing = self._populate_missing_driver_standing(standing)
return DriverStanding(
position=int(standing["position"]),
positionText=standing["positionText"],
position_text=standing["positionText"],
points=float(standing["points"]),
wins=int(standing["wins"]),
driver=self.construct_driver(standing["Driver"]),
@ -273,29 +349,45 @@ class TypeConstructor():
)
def construct_driver_standings(self, standings: dict) -> list[DriverStanding]:
"""
Construct a list of DriverStandings from a JSON dictionary
"""
return [self.construct_driver_standing(standing) for standing in standings]
def construct_constructor_standing(self, standing: dict) -> ConstructorStanding:
"""
Construct a ConstructorStanding from a JSON dictionary
"""
standing = self._populate_missing_constructor_standing(standing)
return ConstructorStanding(
position=int(standing["position"]),
positionText=standing["positionText"],
position_text=standing["positionText"],
points=float(standing["points"]),
wins=int(standing["wins"]),
constructor=self.construct_constructor(standing["Constructor"])
)
def construct_constructor_standings(self, standings: dict) -> list[ConstructorStanding]:
"""
Construct a list of ConstructorStandings from a JSON dictionary
"""
return [self.construct_constructor_standing(standing) for standing in standings]
def construct_standings_list(self, standings_list: dict) -> StandingsList:
"""
Construct a StandingsList from a JSON dictionary
"""
standings_list = self._populate_missing_standings_list(standings_list)
return StandingsList(
season=int(standings_list["season"]),
round=int(standings_list["round"]),
driverStandings=self.construct_driver_standings(standings_list["DriverStandings"]),
constructorStandings=self.construct_constructor_standings(standings_list["ConstructorStandings"])
round_no=int(standings_list["round"]),
driver_standings=self.construct_driver_standings(standings_list["DriverStandings"]),
constructor_standings=self.construct_constructor_standings(
standings_list["ConstructorStandings"])
)
def construct_standings_lists(self, standings_lists: dict) -> list[StandingsList]:
"""
Construct a list of StandingsLists from a JSON dictionary
"""
return [self.construct_standings_list(standings_list) for standings_list in standings_lists]