added new interface/tools
Browse files- api_playground.ipynb +283 -21
- app.py +51 -8
- tools.py +66 -1
api_playground.ipynb
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
-
"execution_count":
|
6 |
"id": "b7d2515e",
|
7 |
"metadata": {},
|
8 |
"outputs": [
|
@@ -19,6 +19,7 @@
|
|
19 |
"import pandas as pd\n",
|
20 |
"from urllib.request import urlopen\n",
|
21 |
"from pprint import pprint\n",
|
|
|
22 |
"import json\n",
|
23 |
"print(\"Successfully loaded in libraries\")"
|
24 |
]
|
@@ -33,41 +34,302 @@
|
|
33 |
},
|
34 |
{
|
35 |
"cell_type": "code",
|
36 |
-
"execution_count":
|
37 |
-
"id": "
|
38 |
"metadata": {},
|
39 |
"outputs": [
|
40 |
{
|
41 |
"name": "stderr",
|
42 |
"output_type": "stream",
|
43 |
"text": [
|
44 |
-
"req WARNING \tDEFAULT CACHE ENABLED! (
|
45 |
-
"core INFO \tLoading data for Bahrain Grand Prix - Race [v3.5.3]\n",
|
46 |
-
"req INFO \tNo cached data found for session_info. Loading data...\n",
|
47 |
-
"_api INFO \tFetching session info data...\n",
|
48 |
-
"req INFO \tData has been written to cache!\n",
|
49 |
-
"req INFO \tNo cached data found for driver_info. Loading data...\n",
|
50 |
-
"_api INFO \tFetching driver list...\n",
|
51 |
-
"req INFO \tData has been written to cache!\n",
|
52 |
-
"req INFO \tNo cached data found for race_control_messages. Loading data...\n",
|
53 |
-
"_api INFO \tFetching race control messages...\n",
|
54 |
-
"req INFO \tData has been written to cache!\n",
|
55 |
-
"core INFO \tFinished loading data for 20 drivers: ['81', '63', '4', '16', '44', '1', '10', '31', '22', '87', '12', '23', '6', '7', '14', '30', '18', '5', '55', '27']\n"
|
56 |
]
|
57 |
},
|
58 |
{
|
59 |
"name": "stdout",
|
60 |
"output_type": "stream",
|
61 |
"text": [
|
62 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
]
|
64 |
}
|
65 |
],
|
66 |
"source": [
|
67 |
"session = fastf1.get_session(2025, 'Bahrain', 'Race')\n",
|
68 |
-
"
|
69 |
-
"
|
70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
]
|
72 |
},
|
73 |
{
|
@@ -424,7 +686,7 @@
|
|
424 |
],
|
425 |
"metadata": {
|
426 |
"kernelspec": {
|
427 |
-
"display_name": "
|
428 |
"language": "python",
|
429 |
"name": "python3"
|
430 |
},
|
@@ -438,7 +700,7 @@
|
|
438 |
"name": "python",
|
439 |
"nbconvert_exporter": "python",
|
440 |
"pygments_lexer": "ipython3",
|
441 |
-
"version": "3.12.
|
442 |
}
|
443 |
},
|
444 |
"nbformat": 4,
|
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
+
"execution_count": 1,
|
6 |
"id": "b7d2515e",
|
7 |
"metadata": {},
|
8 |
"outputs": [
|
|
|
19 |
"import pandas as pd\n",
|
20 |
"from urllib.request import urlopen\n",
|
21 |
"from pprint import pprint\n",
|
22 |
+
"from utils.parser_utils import parse_event_info, parse_season_calendar\n",
|
23 |
"import json\n",
|
24 |
"print(\"Successfully loaded in libraries\")"
|
25 |
]
|
|
|
34 |
},
|
35 |
{
|
36 |
"cell_type": "code",
|
37 |
+
"execution_count": 3,
|
38 |
+
"id": "2815be5b",
|
39 |
"metadata": {},
|
40 |
"outputs": [
|
41 |
{
|
42 |
"name": "stderr",
|
43 |
"output_type": "stream",
|
44 |
"text": [
|
45 |
+
"req WARNING \tDEFAULT CACHE ENABLED! (173.43 MB) /home/arre/.cache/fastf1\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
]
|
47 |
},
|
48 |
{
|
49 |
"name": "stdout",
|
50 |
"output_type": "stream",
|
51 |
"text": [
|
52 |
+
"['api_path',\n",
|
53 |
+
" 'car_data',\n",
|
54 |
+
" 'date',\n",
|
55 |
+
" 'drivers',\n",
|
56 |
+
" 'event',\n",
|
57 |
+
" 'f1_api_support',\n",
|
58 |
+
" 'get_circuit_info',\n",
|
59 |
+
" 'get_driver',\n",
|
60 |
+
" 'laps',\n",
|
61 |
+
" 'load',\n",
|
62 |
+
" 'name',\n",
|
63 |
+
" 'pos_data',\n",
|
64 |
+
" 'race_control_messages',\n",
|
65 |
+
" 'results',\n",
|
66 |
+
" 'session_info',\n",
|
67 |
+
" 'session_start_time',\n",
|
68 |
+
" 'session_status',\n",
|
69 |
+
" 't0_date',\n",
|
70 |
+
" 'total_laps',\n",
|
71 |
+
" 'track_status',\n",
|
72 |
+
" 'weather_data']\n"
|
73 |
]
|
74 |
}
|
75 |
],
|
76 |
"source": [
|
77 |
"session = fastf1.get_session(2025, 'Bahrain', 'Race')\n",
|
78 |
+
"attributes = [x for x in dir(session) if not x.startswith(\"_\")]\n",
|
79 |
+
"pprint(attributes)"
|
80 |
+
]
|
81 |
+
},
|
82 |
+
{
|
83 |
+
"cell_type": "code",
|
84 |
+
"execution_count": 21,
|
85 |
+
"id": "1cc4ab17",
|
86 |
+
"metadata": {},
|
87 |
+
"outputs": [
|
88 |
+
{
|
89 |
+
"name": "stdout",
|
90 |
+
"output_type": "stream",
|
91 |
+
"text": [
|
92 |
+
"ATTR: api_path: /static/2025/2025-04-13_Bahrain_Grand_Prix/2025-04-13_Race/\n",
|
93 |
+
"\n",
|
94 |
+
"Failed to get attribute: car_data\n",
|
95 |
+
"ATTR: date: 2025-04-13 15:00:00\n",
|
96 |
+
"\n",
|
97 |
+
"Failed to get attribute: drivers\n",
|
98 |
+
"ATTR: event: RoundNumber 4\n",
|
99 |
+
"Country Bahrain\n",
|
100 |
+
"Location Sakhir\n",
|
101 |
+
"OfficialEventName FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2025\n",
|
102 |
+
"EventDate 2025-04-13 00:00:00\n",
|
103 |
+
"EventName Bahrain Grand Prix\n",
|
104 |
+
"EventFormat conventional\n",
|
105 |
+
"Session1 Practice 1\n",
|
106 |
+
"Session1Date 2025-04-11 14:30:00+03:00\n",
|
107 |
+
"Session1DateUtc 2025-04-11 11:30:00\n",
|
108 |
+
"Session2 Practice 2\n",
|
109 |
+
"Session2Date 2025-04-11 18:00:00+03:00\n",
|
110 |
+
"Session2DateUtc 2025-04-11 15:00:00\n",
|
111 |
+
"Session3 Practice 3\n",
|
112 |
+
"Session3Date 2025-04-12 15:30:00+03:00\n",
|
113 |
+
"Session3DateUtc 2025-04-12 12:30:00\n",
|
114 |
+
"Session4 Qualifying\n",
|
115 |
+
"Session4Date 2025-04-12 19:00:00+03:00\n",
|
116 |
+
"Session4DateUtc 2025-04-12 16:00:00\n",
|
117 |
+
"Session5 Race\n",
|
118 |
+
"Session5Date 2025-04-13 18:00:00+03:00\n",
|
119 |
+
"Session5DateUtc 2025-04-13 15:00:00\n",
|
120 |
+
"F1ApiSupport True\n",
|
121 |
+
"Name: 4, dtype: object\n",
|
122 |
+
"\n",
|
123 |
+
"ATTR: f1_api_support: True\n",
|
124 |
+
"\n",
|
125 |
+
"ATTR: get_circuit_info: <bound method Session.get_circuit_info of 2025 Season Round 4: Bahrain Grand Prix - Race>\n",
|
126 |
+
"\n",
|
127 |
+
"ATTR: get_driver: <bound method Session.get_driver of 2025 Season Round 4: Bahrain Grand Prix - Race>\n",
|
128 |
+
"\n",
|
129 |
+
"Failed to get attribute: laps\n",
|
130 |
+
"ATTR: load: <bound method Session.load of 2025 Season Round 4: Bahrain Grand Prix - Race>\n",
|
131 |
+
"\n",
|
132 |
+
"ATTR: name: Race\n",
|
133 |
+
"\n",
|
134 |
+
"Failed to get attribute: pos_data\n",
|
135 |
+
"Failed to get attribute: race_control_messages\n",
|
136 |
+
"Failed to get attribute: results\n",
|
137 |
+
"Failed to get attribute: session_info\n",
|
138 |
+
"Failed to get attribute: session_start_time\n",
|
139 |
+
"Failed to get attribute: session_status\n",
|
140 |
+
"Failed to get attribute: t0_date\n",
|
141 |
+
"Failed to get attribute: total_laps\n",
|
142 |
+
"Failed to get attribute: track_status\n",
|
143 |
+
"Failed to get attribute: weather_data\n"
|
144 |
+
]
|
145 |
+
}
|
146 |
+
],
|
147 |
+
"source": [
|
148 |
+
"for attr in attributes:\n",
|
149 |
+
" try:\n",
|
150 |
+
" print(f\"ATTR: {attr}: {getattr(session, attr)}\\n\")\n",
|
151 |
+
" except:\n",
|
152 |
+
" print(f\"Failed to get attribute: {attr}\")"
|
153 |
+
]
|
154 |
+
},
|
155 |
+
{
|
156 |
+
"cell_type": "code",
|
157 |
+
"execution_count": 10,
|
158 |
+
"id": "44a4b93b",
|
159 |
+
"metadata": {},
|
160 |
+
"outputs": [
|
161 |
+
{
|
162 |
+
"name": "stdout",
|
163 |
+
"output_type": "stream",
|
164 |
+
"text": [
|
165 |
+
"RoundNumber 4\n",
|
166 |
+
"Country Bahrain\n",
|
167 |
+
"Location Sakhir\n",
|
168 |
+
"OfficialEventName FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2025\n",
|
169 |
+
"EventDate 2025-04-13 00:00:00\n",
|
170 |
+
"EventName Bahrain Grand Prix\n",
|
171 |
+
"EventFormat conventional\n",
|
172 |
+
"Session1 Practice 1\n",
|
173 |
+
"Session1Date 2025-04-11 14:30:00+03:00\n",
|
174 |
+
"Session1DateUtc 2025-04-11 11:30:00\n",
|
175 |
+
"Session2 Practice 2\n",
|
176 |
+
"Session2Date 2025-04-11 18:00:00+03:00\n",
|
177 |
+
"Session2DateUtc 2025-04-11 15:00:00\n",
|
178 |
+
"Session3 Practice 3\n",
|
179 |
+
"Session3Date 2025-04-12 15:30:00+03:00\n",
|
180 |
+
"Session3DateUtc 2025-04-12 12:30:00\n",
|
181 |
+
"Session4 Qualifying\n",
|
182 |
+
"Session4Date 2025-04-12 19:00:00+03:00\n",
|
183 |
+
"Session4DateUtc 2025-04-12 16:00:00\n",
|
184 |
+
"Session5 Race\n",
|
185 |
+
"Session5Date 2025-04-13 18:00:00+03:00\n",
|
186 |
+
"Session5DateUtc 2025-04-13 15:00:00\n",
|
187 |
+
"F1ApiSupport True\n",
|
188 |
+
"Name: 4, dtype: object\n",
|
189 |
+
"RoundNumber 4\n",
|
190 |
+
"Country Bahrain\n",
|
191 |
+
"Location Sakhir\n",
|
192 |
+
"OfficialEventName FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2025\n",
|
193 |
+
"EventDate 2025-04-13 00:00:00\n",
|
194 |
+
"EventName Bahrain Grand Prix\n",
|
195 |
+
"EventFormat conventional\n",
|
196 |
+
"Session1 Practice 1\n",
|
197 |
+
"Session1Date 2025-04-11 14:30:00+03:00\n",
|
198 |
+
"Session1DateUtc 2025-04-11 11:30:00\n",
|
199 |
+
"Session2 Practice 2\n",
|
200 |
+
"Session2Date 2025-04-11 18:00:00+03:00\n",
|
201 |
+
"Session2DateUtc 2025-04-11 15:00:00\n",
|
202 |
+
"Session3 Practice 3\n",
|
203 |
+
"Session3Date 2025-04-12 15:30:00+03:00\n",
|
204 |
+
"Session3DateUtc 2025-04-12 12:30:00\n",
|
205 |
+
"Session4 Qualifying\n",
|
206 |
+
"Session4Date 2025-04-12 19:00:00+03:00\n",
|
207 |
+
"Session4DateUtc 2025-04-12 16:00:00\n",
|
208 |
+
"Session5 Race\n",
|
209 |
+
"Session5Date 2025-04-13 18:00:00+03:00\n",
|
210 |
+
"Session5DateUtc 2025-04-13 15:00:00\n",
|
211 |
+
"F1ApiSupport True\n",
|
212 |
+
"Name: 4, dtype: object\n"
|
213 |
+
]
|
214 |
+
}
|
215 |
+
],
|
216 |
+
"source": [
|
217 |
+
"event1 = fastf1.get_session(2025, 'Bahrain', \"fp1\").event\n",
|
218 |
+
"print(event1)\n",
|
219 |
+
"event2 = fastf1.get_session(2025, 'Bahrain', \"race\").event\n",
|
220 |
+
"print(event2)"
|
221 |
+
]
|
222 |
+
},
|
223 |
+
{
|
224 |
+
"cell_type": "code",
|
225 |
+
"execution_count": null,
|
226 |
+
"id": "067ab2ac",
|
227 |
+
"metadata": {},
|
228 |
+
"outputs": [
|
229 |
+
{
|
230 |
+
"name": "stdout",
|
231 |
+
"output_type": "stream",
|
232 |
+
"text": [
|
233 |
+
"<class 'fastf1.events.Event'>\n",
|
234 |
+
"RoundNumber 4\n",
|
235 |
+
"Country Bahrain\n",
|
236 |
+
"Location Sakhir\n",
|
237 |
+
"OfficialEventName FORMULA 1 GULF AIR BAHRAIN GRAND PRIX 2025\n",
|
238 |
+
"EventDate 2025-04-13 00:00:00\n",
|
239 |
+
"EventName Bahrain Grand Prix\n",
|
240 |
+
"EventFormat conventional\n",
|
241 |
+
"Session1 Practice 1\n",
|
242 |
+
"Session1Date 2025-04-11 14:30:00+03:00\n",
|
243 |
+
"Session1DateUtc 2025-04-11 11:30:00\n",
|
244 |
+
"Session2 Practice 2\n",
|
245 |
+
"Session2Date 2025-04-11 18:00:00+03:00\n",
|
246 |
+
"Session2DateUtc 2025-04-11 15:00:00\n",
|
247 |
+
"Session3 Practice 3\n",
|
248 |
+
"Session3Date 2025-04-12 15:30:00+03:00\n",
|
249 |
+
"Session3DateUtc 2025-04-12 12:30:00\n",
|
250 |
+
"Session4 Qualifying\n",
|
251 |
+
"Session4Date 2025-04-12 19:00:00+03:00\n",
|
252 |
+
"Session4DateUtc 2025-04-12 16:00:00\n",
|
253 |
+
"Session5 Race\n",
|
254 |
+
"Session5Date 2025-04-13 18:00:00+03:00\n",
|
255 |
+
"Session5DateUtc 2025-04-13 15:00:00\n",
|
256 |
+
"F1ApiSupport True\n",
|
257 |
+
"Name: 4, dtype: object\n"
|
258 |
+
]
|
259 |
+
}
|
260 |
+
],
|
261 |
+
"source": [
|
262 |
+
"event2 = fastf1.get_event(2025, 'Bahrain')\n",
|
263 |
+
"print(type(event2))\n",
|
264 |
+
"print(event2.keys())\n"
|
265 |
+
]
|
266 |
+
},
|
267 |
+
{
|
268 |
+
"cell_type": "code",
|
269 |
+
"execution_count": 2,
|
270 |
+
"id": "32f180c1",
|
271 |
+
"metadata": {},
|
272 |
+
"outputs": [
|
273 |
+
{
|
274 |
+
"name": "stderr",
|
275 |
+
"output_type": "stream",
|
276 |
+
"text": [
|
277 |
+
"req WARNING \tDEFAULT CACHE ENABLED! (173.47 MB) /home/arre/.cache/fastf1\n"
|
278 |
+
]
|
279 |
+
},
|
280 |
+
{
|
281 |
+
"name": "stdout",
|
282 |
+
"output_type": "stream",
|
283 |
+
"text": [
|
284 |
+
"RoundNumber 1\n",
|
285 |
+
"Country Australia\n",
|
286 |
+
"Location Melbourne\n",
|
287 |
+
"OfficialEventName \n",
|
288 |
+
"EventDate 2007-03-18 03:00:00\n",
|
289 |
+
"EventName Australian Grand Prix\n",
|
290 |
+
"EventFormat conventional\n",
|
291 |
+
"Session1 Practice 1\n",
|
292 |
+
"Session1Date None\n",
|
293 |
+
"Session1DateUtc 2007-03-16 00:00:00\n",
|
294 |
+
"Session2 Practice 2\n",
|
295 |
+
"Session2Date None\n",
|
296 |
+
"Session2DateUtc 2007-03-16 00:00:00\n",
|
297 |
+
"Session3 Practice 3\n",
|
298 |
+
"Session3Date None\n",
|
299 |
+
"Session3DateUtc 2007-03-17 00:00:00\n",
|
300 |
+
"Session4 Qualifying\n",
|
301 |
+
"Session4Date None\n",
|
302 |
+
"Session4DateUtc 2007-03-17 00:00:00\n",
|
303 |
+
"Session5 Race\n",
|
304 |
+
"Session5Date None\n",
|
305 |
+
"Session5DateUtc 2007-03-18 03:00:00\n",
|
306 |
+
"F1ApiSupport False\n",
|
307 |
+
"Name: 0, dtype: object\n",
|
308 |
+
"Season calendar:\n",
|
309 |
+
"Round 1 : Australian Grand Prix - Melbourne, Australia (2007-03-16 - 2007-03-18)\n",
|
310 |
+
"Round 2 : Malaysian Grand Prix - Kuala Lumpur, Malaysia (2007-04-06 - 2007-04-08)\n",
|
311 |
+
"Round 3 : Bahrain Grand Prix - Sakhir, Bahrain (2007-04-13 - 2007-04-15)\n",
|
312 |
+
"Round 4 : Spanish Grand Prix - Montmeló, Spain (2007-05-11 - 2007-05-13)\n",
|
313 |
+
"Round 5 : Monaco Grand Prix - Monte-Carlo, Monaco (2007-05-25 - 2007-05-27)\n",
|
314 |
+
"Round 6 : Canadian Grand Prix - Montreal, Canada (2007-06-08 - 2007-06-10)\n",
|
315 |
+
"Round 7 : United States Grand Prix - Indianapolis, USA (2007-06-15 - 2007-06-17)\n",
|
316 |
+
"Round 8 : French Grand Prix - Magny Cours, France (2007-06-29 - 2007-07-01)\n",
|
317 |
+
"Round 9 : British Grand Prix - Silverstone, UK (2007-07-06 - 2007-07-08)\n",
|
318 |
+
"Round 10 : European Grand Prix - Nürburg, Germany (2007-07-20 - 2007-07-22)\n",
|
319 |
+
"Round 11 : Hungarian Grand Prix - Budapest, Hungary (2007-08-03 - 2007-08-05)\n",
|
320 |
+
"Round 12 : Turkish Grand Prix - Istanbul, Turkey (2007-08-24 - 2007-08-26)\n",
|
321 |
+
"Round 13 : Italian Grand Prix - Monza, Italy (2007-09-07 - 2007-09-09)\n",
|
322 |
+
"Round 14 : Belgian Grand Prix - Spa, Belgium (2007-09-14 - 2007-09-16)\n",
|
323 |
+
"Round 15 : Japanese Grand Prix - Oyama, Japan (2007-09-28 - 2007-09-30)\n",
|
324 |
+
"Round 16 : Chinese Grand Prix - Shanghai, China (2007-10-05 - 2007-10-07)\n",
|
325 |
+
"Round 17 : Brazilian Grand Prix - São Paulo, Brazil (2007-10-19 - 2007-10-21)\n"
|
326 |
+
]
|
327 |
+
}
|
328 |
+
],
|
329 |
+
"source": [
|
330 |
+
"schedule = fastf1.get_event_schedule(2007)\n",
|
331 |
+
"print(schedule.iloc[0])\n",
|
332 |
+
"print(parse_season_calendar(schedule))"
|
333 |
]
|
334 |
},
|
335 |
{
|
|
|
686 |
],
|
687 |
"metadata": {
|
688 |
"kernelspec": {
|
689 |
+
"display_name": "hackaton",
|
690 |
"language": "python",
|
691 |
"name": "python3"
|
692 |
},
|
|
|
700 |
"name": "python",
|
701 |
"nbconvert_exporter": "python",
|
702 |
"pygments_lexer": "ipython3",
|
703 |
+
"version": "3.12.9"
|
704 |
}
|
705 |
},
|
706 |
"nbformat": 4,
|
app.py
CHANGED
@@ -1,6 +1,18 @@
|
|
|
|
1 |
import random
|
|
|
2 |
import gradio as gr
|
3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
def driver_championship_score(driver_name: str) -> str:
|
5 |
"""
|
6 |
Get the championship score for the given driver.
|
@@ -27,26 +39,57 @@ def driver_position(driver_name: str) -> str:
|
|
27 |
return f"Driver {driver_name} is in position {random.randint(1, 20)}"
|
28 |
|
29 |
|
|
|
|
|
|
|
30 |
|
31 |
-
# Create interfaces for each tool
|
32 |
iface1 = gr.Interface(
|
33 |
fn=driver_championship_score,
|
34 |
-
inputs=
|
35 |
outputs="text",
|
36 |
-
title="[
|
|
|
37 |
)
|
38 |
|
39 |
iface2 = gr.Interface(
|
40 |
fn=driver_position,
|
41 |
-
inputs=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
outputs="text",
|
43 |
-
title="
|
|
|
44 |
)
|
45 |
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
gradio_server = gr.TabbedInterface(
|
48 |
-
|
49 |
-
tab_names=
|
50 |
title="Formula 1 MCP server"
|
51 |
)
|
52 |
|
|
|
1 |
+
import json
|
2 |
import random
|
3 |
+
import datetime
|
4 |
import gradio as gr
|
5 |
|
6 |
+
# Local modules
|
7 |
+
import tools
|
8 |
+
from utils.constants import (
|
9 |
+
AVAILABLE_SESSION_TYPES,
|
10 |
+
DROPDOWN_SESSION_TYPES
|
11 |
+
)
|
12 |
+
|
13 |
+
# Variables
|
14 |
+
CURRENT_YEAR = datetime.datetime.now().year
|
15 |
+
|
16 |
def driver_championship_score(driver_name: str) -> str:
|
17 |
"""
|
18 |
Get the championship score for the given driver.
|
|
|
39 |
return f"Driver {driver_name} is in position {random.randint(1, 20)}"
|
40 |
|
41 |
|
42 |
+
# Load in driver names
|
43 |
+
with open("assets/driver_names.json") as f:
|
44 |
+
driver_names = json.load(f)["drivers"]
|
45 |
|
|
|
46 |
iface1 = gr.Interface(
|
47 |
fn=driver_championship_score,
|
48 |
+
inputs=gr.Dropdown(driver_names),
|
49 |
outputs="text",
|
50 |
+
title="[WIP] Driver Championship Score",
|
51 |
+
description="Get the championship score for the given driver"
|
52 |
)
|
53 |
|
54 |
iface2 = gr.Interface(
|
55 |
fn=driver_position,
|
56 |
+
inputs=gr.Dropdown(driver_names),
|
57 |
+
outputs="text",
|
58 |
+
title="[WIP] Driver Position",
|
59 |
+
description="Get the current position of the given driver"
|
60 |
+
)
|
61 |
+
|
62 |
+
iface3 = gr.Interface(
|
63 |
+
fn=tools.get_event_info,
|
64 |
+
inputs=[
|
65 |
+
gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
|
66 |
+
gr.Textbox(label="Grand Prix", placeholder="Ex: Monaco", info="The name of the GP/country/location (Fuzzy matching supported)"),
|
67 |
+
gr.Radio(["human", "LLM"], label="Format", value="human")
|
68 |
+
],
|
69 |
outputs="text",
|
70 |
+
title="Event Info",
|
71 |
+
description="Get the Grand Prix event info for a specific race week"
|
72 |
)
|
73 |
|
74 |
+
iface4 = gr.Interface(
|
75 |
+
fn=tools.get_season_calendar,
|
76 |
+
inputs=[
|
77 |
+
gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
|
78 |
+
],
|
79 |
+
outputs="text",
|
80 |
+
title="Season Calendar",
|
81 |
+
description="Get the season calendar information for the given year"
|
82 |
+
)
|
83 |
+
|
84 |
+
|
85 |
+
interface_list = [iface1, iface2, iface3, iface4]
|
86 |
+
tab_names = ["[WIP] Driver Championship Score", "[WIP] Driver Position", "Event Info", "Season Calendar"]
|
87 |
+
|
88 |
+
|
89 |
+
# Combine all the interfaces into a single TabbedInterface
|
90 |
gradio_server = gr.TabbedInterface(
|
91 |
+
interface_list,
|
92 |
+
tab_names=tab_names,
|
93 |
title="Formula 1 MCP server"
|
94 |
)
|
95 |
|
tools.py
CHANGED
@@ -1 +1,66 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Here we implement the MCP tools
|
3 |
+
|
4 |
+
Tools to implement
|
5 |
+
- session result
|
6 |
+
- driver info
|
7 |
+
- championship standings
|
8 |
+
- driver standings
|
9 |
+
- compare drivers
|
10 |
+
|
11 |
+
"""
|
12 |
+
|
13 |
+
|
14 |
+
## Here we implement the MCP tools
|
15 |
+
import fastf1
|
16 |
+
from utils.constants import AVAILABLE_SESSION_TYPES
|
17 |
+
|
18 |
+
from fastf1.core import Session
|
19 |
+
from typing import Union
|
20 |
+
|
21 |
+
from utils import parser_utils
|
22 |
+
|
23 |
+
# Custom types
|
24 |
+
gp = Union[str, int]
|
25 |
+
session_type = Union[str, int, None]
|
26 |
+
|
27 |
+
def get_season_calendar(year: int) -> str:
|
28 |
+
""" Returns the season calendar for the given year """
|
29 |
+
season_calendar = fastf1.get_event_schedule(year)
|
30 |
+
return parser_utils.parse_season_calendar(season_calendar)
|
31 |
+
|
32 |
+
def get_session(year: int, round: gp, session_type: session_type) -> Session:
|
33 |
+
"""
|
34 |
+
Returns a session specified by year, round and session type
|
35 |
+
"""
|
36 |
+
|
37 |
+
# Check if session type is valid
|
38 |
+
if isinstance(session_type, str):
|
39 |
+
if session_type.lower() not in AVAILABLE_SESSION_TYPES:
|
40 |
+
return f"Session type {session_type} is not available. Supported session types: {AVAILABLE_SESSION_TYPES}"
|
41 |
+
|
42 |
+
return fastf1.get_session(year, round, session_type)
|
43 |
+
|
44 |
+
def get_event_info(year: int, round: gp, format: str) -> str:
|
45 |
+
""" Returns the event info for the specified session """
|
46 |
+
|
47 |
+
event = fastf1.get_session(year, round, "race").event # Event object is the same for all sessions, so hardcode "race"
|
48 |
+
if format == "human":
|
49 |
+
data_interval = f"{event['Session1DateUtc'].date()} - {event['Session5DateUtc'].date()}"
|
50 |
+
event_string = f"Round {event['RoundNumber']} : {event['EventName']} - {event['Location']}, {event['Country']} ({data_interval})"
|
51 |
+
return event_string
|
52 |
+
elif format == "LLM":
|
53 |
+
return parser_utils.parse_event_info(event)
|
54 |
+
|
55 |
+
|
56 |
+
def get_constructor_standings(year: int) -> str:
|
57 |
+
pass
|
58 |
+
|
59 |
+
def get_driver_standings(year):
|
60 |
+
pass
|
61 |
+
|
62 |
+
|
63 |
+
|
64 |
+
if __name__ == "__main__":
|
65 |
+
session = get_session(2024, 1, "fp1")
|
66 |
+
session.load()
|