codebase refactoring
Browse files- README.md +2 -2
- assets/driver_abbreviations.json +0 -22
- fastf1_tools.py +0 -33
- openf1_tools.py +1 -24
- todo.txt +1 -1
- utils/constants.py +12 -17
- utils/track_utils.py +4 -4
README.md
CHANGED
@@ -17,13 +17,13 @@ tags:
|
|
17 |
|
18 |
|
19 |
## MCP Server
|
20 |
-
|
21 |
The MCP server is defined inside `app.py` and is hosted on HuggingFace spaces using the Gradio template.
|
22 |
|
23 |
## MCP Client
|
24 |
-
|
25 |
The MCP client and AI agent is defined inside `mcp_client.py` and allows interaction with the MCP server through server side events (SSE) transport.
|
26 |
|
|
|
|
|
27 |
For MCP clients that support SSE transport (for Claude Desktop, see below), the following configuration can be used:
|
28 |
|
29 |
```json
|
|
|
17 |
|
18 |
|
19 |
## MCP Server
|
|
|
20 |
The MCP server is defined inside `app.py` and is hosted on HuggingFace spaces using the Gradio template.
|
21 |
|
22 |
## MCP Client
|
|
|
23 |
The MCP client and AI agent is defined inside `mcp_client.py` and allows interaction with the MCP server through server side events (SSE) transport.
|
24 |
|
25 |
+
|
26 |
+
## MCP configuration file
|
27 |
For MCP clients that support SSE transport (for Claude Desktop, see below), the following configuration can be used:
|
28 |
|
29 |
```json
|
assets/driver_abbreviations.json
DELETED
@@ -1,22 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"Max Verstappen": "VER",
|
3 |
-
"Liam Lawson": "LAW",
|
4 |
-
"Charles Leclerc": "LEC",
|
5 |
-
"Lewis Hamilton": "HAM",
|
6 |
-
"George Russell": "RUS",
|
7 |
-
"Andrea Kimi Antonelli": "ANT",
|
8 |
-
"Lando Norris": "NOR",
|
9 |
-
"Oscar Piastri": "PIA",
|
10 |
-
"Fernando Alonso": "ALO",
|
11 |
-
"Lance Stroll": "STR",
|
12 |
-
"Pierre Gasly": "GAS",
|
13 |
-
"Jack Doohan": "DOO",
|
14 |
-
"Esteban Ocon": "OCO",
|
15 |
-
"Oliver Bearman": "BEA",
|
16 |
-
"Yuki Tsunoda": "TSU",
|
17 |
-
"Isack Hadjar": "HAD",
|
18 |
-
"Alexander Albon": "ALB",
|
19 |
-
"Carlos Sainz Jr": "SAI",
|
20 |
-
"Nico Hülkenberg": "HUL",
|
21 |
-
"Gabriel Bortoleto": "BOR"
|
22 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fastf1_tools.py
CHANGED
@@ -1,12 +1,3 @@
|
|
1 |
-
"""
|
2 |
-
This module provides tools for interacting with Formula 1 data using the FastF1 library.
|
3 |
-
|
4 |
-
Tools to implement
|
5 |
-
- driver info
|
6 |
-
- compare drivers
|
7 |
-
"""
|
8 |
-
|
9 |
-
import json
|
10 |
import fastf1
|
11 |
import gradio as gr
|
12 |
import pandas as pd
|
@@ -90,29 +81,6 @@ def get_event_info(year: int, round: gp, format: str) -> str:
|
|
90 |
elif format == "LLM":
|
91 |
return parser_utils.parse_event_info(event)
|
92 |
|
93 |
-
|
94 |
-
def get_constructor_standings(year: int) -> str:
|
95 |
-
"""Retrieve constructor championship standings for a given year.
|
96 |
-
|
97 |
-
Args:
|
98 |
-
year (int): The season year
|
99 |
-
|
100 |
-
Returns:
|
101 |
-
str: Constructor championship standings
|
102 |
-
"""
|
103 |
-
pass
|
104 |
-
|
105 |
-
def get_driver_standings(year: int) -> str:
|
106 |
-
"""Retrieve driver championship standings for a given year.
|
107 |
-
|
108 |
-
Args:
|
109 |
-
year (int): The season year
|
110 |
-
|
111 |
-
Returns:
|
112 |
-
str: Driver championship standings
|
113 |
-
"""
|
114 |
-
pass
|
115 |
-
|
116 |
def driver_championship_standings(year: int, driver_name: str) -> str:
|
117 |
"""Get the championship standing for a specific driver in a given year.
|
118 |
|
@@ -247,7 +215,6 @@ def get_constructor_info(constructor_name: str) -> str:
|
|
247 |
return constructor_info_string
|
248 |
|
249 |
|
250 |
-
|
251 |
if __name__ == "__main__":
|
252 |
session = get_session(2024, 1, "fp1")
|
253 |
session.load()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import fastf1
|
2 |
import gradio as gr
|
3 |
import pandas as pd
|
|
|
81 |
elif format == "LLM":
|
82 |
return parser_utils.parse_event_info(event)
|
83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
def driver_championship_standings(year: int, driver_name: str) -> str:
|
85 |
"""Get the championship standing for a specific driver in a given year.
|
86 |
|
|
|
215 |
return constructor_info_string
|
216 |
|
217 |
|
|
|
218 |
if __name__ == "__main__":
|
219 |
session = get_session(2024, 1, "fp1")
|
220 |
session.load()
|
openf1_tools.py
CHANGED
@@ -2,17 +2,8 @@ import json
|
|
2 |
from urllib.request import urlopen
|
3 |
from openf1_registry import f1_api, api_endpoints
|
4 |
|
5 |
-
|
6 |
### Essential tools ###
|
7 |
|
8 |
-
def get_current_time() -> str:
|
9 |
-
"""
|
10 |
-
Retrieve the current time in ISO 8601 format.
|
11 |
-
|
12 |
-
Returns:
|
13 |
-
str: The current time in ISO 8601 format.
|
14 |
-
"""
|
15 |
-
|
16 |
def get_api_endpoint(endpoint: str) -> dict:
|
17 |
"""
|
18 |
Retrieve the API endpoint URL and filter metadata for a given OpenF1 endpoint.
|
@@ -140,18 +131,4 @@ def get_filter_info(filter_name: str) -> dict:
|
|
140 |
return {
|
141 |
"filter_name": filter_name,
|
142 |
"filter_metadata": f1_api.get_filter_help(filter_name)
|
143 |
-
}
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
if __name__ == "__main__":
|
150 |
-
|
151 |
-
from pprint import pprint
|
152 |
-
|
153 |
-
data = get_api_endpoint("sessions")
|
154 |
-
pprint(data)
|
155 |
-
|
156 |
-
pprint(get_endpoint_info("sessions"))
|
157 |
-
|
|
|
2 |
from urllib.request import urlopen
|
3 |
from openf1_registry import f1_api, api_endpoints
|
4 |
|
|
|
5 |
### Essential tools ###
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
def get_api_endpoint(endpoint: str) -> dict:
|
8 |
"""
|
9 |
Retrieve the API endpoint URL and filter metadata for a given OpenF1 endpoint.
|
|
|
131 |
return {
|
132 |
"filter_name": filter_name,
|
133 |
"filter_metadata": f1_api.get_filter_help(filter_name)
|
134 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
todo.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
|
|
1 |
- host agent using Modal labs
|
2 |
- Record demonstration using Loom and add link to README
|
3 |
* Demo the Gradio UI
|
4 |
* Demo the MCP client using Claude Desktop
|
5 |
* Demo the MCP client using mcp_client.py
|
6 |
|
7 |
-
More info about the Gradio agent: https://www.gradio.app/guides/agents-and-tool-usage
|
8 |
|
9 |
Side sponsor wins
|
10 |
- Modal labs choice (host a LLM on their platform using vLLM or ollama)
|
|
|
1 |
+
More info about the Gradio agent: https://www.gradio.app/guides/agents-and-tool-usage
|
2 |
- host agent using Modal labs
|
3 |
- Record demonstration using Loom and add link to README
|
4 |
* Demo the Gradio UI
|
5 |
* Demo the MCP client using Claude Desktop
|
6 |
* Demo the MCP client using mcp_client.py
|
7 |
|
|
|
8 |
|
9 |
Side sponsor wins
|
10 |
- Modal labs choice (host a LLM on their platform using vLLM or ollama)
|
utils/constants.py
CHANGED
@@ -63,14 +63,15 @@ This application leverages the FastF1 library and OpenF1 API to provide detailed
|
|
63 |
|
64 |
There are different ways to interact with the MCP server:
|
65 |
|
66 |
-
1) (recommended) Add the MCP server to your `mcp.json` file. This is the most user-friendly way to interact with the MCP server. See the section below for the config file.
|
67 |
|
68 |
-
2) (
|
69 |
|
70 |
-
3) (
|
71 |
|
72 |
|
73 |
-
|
|
|
74 |
|
75 |
For MCP clients that support SSE transport (For Claude desktop see below), the following configuration can be used in your `mcp.json` file (or its equivalent):
|
76 |
|
@@ -121,35 +122,29 @@ The implemented functions make it possible to:
|
|
121 |
- Apply filters to an API string - `apply_filters(api_string, *filters)`
|
122 |
- Send a request to the OpenF1 API - `send_request(api_string)`
|
123 |
|
124 |
-
The inputs are strings while the output is a JSON object. The examples are listed in an order that would be expected to be used in a real-life scenario. Some example API strings are listed below in the
|
125 |
|
126 |
"""
|
127 |
|
128 |
|
129 |
MARKDOWN_OPENF1_EXAMPLES = """
|
130 |
|
131 |
-
|
132 |
-
|
133 |
```https://api.openf1.org/v1/car_data?driver_number=55&session_key=9159&speed>=315```
|
134 |
|
135 |
-
|
136 |
-
|
137 |
```https://api.openf1.org/v1/drivers?driver_number=1&session_key=9158```
|
138 |
|
139 |
-
|
140 |
-
|
141 |
```https://api.openf1.org/v1/intervals?session_key=9165&interval<0.005```
|
142 |
|
143 |
-
|
144 |
-
|
145 |
```https://api.openf1.org/v1/laps?session_key=9161&driver_number=63&lap_number=8```
|
146 |
|
147 |
-
|
148 |
-
|
149 |
```https://api.openf1.org/v1/meetings?year=2023&country_name=Singapore```
|
150 |
|
151 |
-
|
152 |
-
|
153 |
```https://api.openf1.org/v1/pit?session_key=9158&pit_duration<31```
|
154 |
|
155 |
"""
|
|
|
63 |
|
64 |
There are different ways to interact with the MCP server:
|
65 |
|
66 |
+
1) (recommended) Add the MCP server to your `mcp.json` file. This is the most user-friendly way to interact with the MCP server. See the section below for the MCP config file.
|
67 |
|
68 |
+
2) (Good for demo) One can also use the Gradio interface directly to interact with the MCP server's tools. Note, however, the UI for the OpenF1 tools is purely limted to strings and JSON.
|
69 |
|
70 |
+
3) (Advanced) One can establish an MCP client by running `mcp_client.py`. This client is connected to the MCP server hosted on HuggingFace spaces.
|
71 |
|
72 |
|
73 |
+
|
74 |
+
## MCP json configuration file
|
75 |
|
76 |
For MCP clients that support SSE transport (For Claude desktop see below), the following configuration can be used in your `mcp.json` file (or its equivalent):
|
77 |
|
|
|
122 |
- Apply filters to an API string - `apply_filters(api_string, *filters)`
|
123 |
- Send a request to the OpenF1 API - `send_request(api_string)`
|
124 |
|
125 |
+
The inputs are strings while the output is a JSON object. The examples are listed in an order that would be expected to be used in a real-life scenario. Some example API strings are listed below in the final tool `send_request(api_string)`.
|
126 |
|
127 |
"""
|
128 |
|
129 |
|
130 |
MARKDOWN_OPENF1_EXAMPLES = """
|
131 |
|
132 |
+
Retrieve data about car number 55 with session_key 9159 where the speed was greater than 315 <br>
|
|
|
133 |
```https://api.openf1.org/v1/car_data?driver_number=55&session_key=9159&speed>=315```
|
134 |
|
135 |
+
Retrieve data about driver number 1 with session_key 9158 <br>
|
|
|
136 |
```https://api.openf1.org/v1/drivers?driver_number=1&session_key=9158```
|
137 |
|
138 |
+
Retrieve data about intervals with session_key 9165 where the interval was less than 0.005s <br>
|
|
|
139 |
```https://api.openf1.org/v1/intervals?session_key=9165&interval<0.005```
|
140 |
|
141 |
+
Retrieve data about laps with session_key 9161 for driver number 63 on lap number 8 <br>
|
|
|
142 |
```https://api.openf1.org/v1/laps?session_key=9161&driver_number=63&lap_number=8```
|
143 |
|
144 |
+
Retrieve data about meetings in 2023 for Singapore <br>
|
|
|
145 |
```https://api.openf1.org/v1/meetings?year=2023&country_name=Singapore```
|
146 |
|
147 |
+
Retrieve data about pit stops with session_key 9158 where the pit duration was less than 31s <br>
|
|
|
148 |
```https://api.openf1.org/v1/pit?session_key=9158&pit_duration<31```
|
149 |
|
150 |
"""
|
utils/track_utils.py
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
-
import matplotlib as mpl
|
2 |
import numpy as np
|
3 |
-
|
4 |
-
|
5 |
from PIL import Image
|
6 |
from io import BytesIO
|
7 |
from typing import Union
|
8 |
-
import json
|
9 |
from fastf1.core import Session
|
|
|
|
|
10 |
|
11 |
# Custom types
|
12 |
gp = Union[str, int]
|
|
|
|
|
1 |
import numpy as np
|
2 |
+
import matplotlib as mpl
|
3 |
+
|
4 |
from PIL import Image
|
5 |
from io import BytesIO
|
6 |
from typing import Union
|
|
|
7 |
from fastf1.core import Session
|
8 |
+
from matplotlib import pyplot as plt
|
9 |
+
from matplotlib.collections import LineCollection
|
10 |
|
11 |
# Custom types
|
12 |
gp = Union[str, int]
|