File size: 9,445 Bytes
014f597 1d0b9d1 89c9126 35aeee0 655dcc9 89c9126 44e58a6 c6542ed 6269c32 655dcc9 89c9126 6bdfadb 35aeee0 6bdfadb 44e58a6 6bdfadb 89c9126 18c04d1 44e58a6 35aeee0 44e58a6 18c04d1 89c9126 6bdfadb 35aeee0 89c9126 18c04d1 b139634 89c9126 1d0b9d1 89c9126 18c04d1 014f597 6bdfadb 35aeee0 89c9126 18c04d1 89c9126 6bdfadb 35aeee0 6bdfadb 18c04d1 6bdfadb b139634 18c04d1 6bdfadb c6542ed 35aeee0 c6542ed 18c04d1 c6542ed 18c04d1 c6542ed 18c04d1 c6542ed 6269c32 35aeee0 6269c32 18c04d1 6269c32 6bdfadb 95e43e2 18c04d1 95e43e2 d07810d d69ce5a 95e43e2 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 1d33ca6 655dcc9 d69ce5a 6bdfadb 97a44d4 b139634 44e58a6 b139634 c6542ed 6269c32 97a44d4 95e43e2 655dcc9 6bdfadb 89c9126 b139634 89c9126 1d0b9d1 89c9126 97a44d4 1d0b9d1 014f597 1d0b9d1 014f597 1d0b9d1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
import gradio as gr
# Local modules
import fastf1_tools
import openf1_tools
from utils.constants import (
DRIVER_NAMES,
CONSTRUCTOR_NAMES,
CURRENT_YEAR,
DROPDOWN_SESSION_TYPES,
MARKDOWN_INTRODUCTION,
MARKDOWN_OPENF1_EXAMPLES,
OPENF1_TOOL_DESCRIPTION
)
iface_driver_championship_standings = gr.Interface(
fn=fastf1_tools.driver_championship_standings,
inputs=[
gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
gr.Dropdown(label="Driver", choices=DRIVER_NAMES)
],
outputs="text",
title="World Driver Championship Standings",
description="Get the world driver championship standings for a specific driver"
)
iface_constructor_championship_standings = gr.Interface(
fn=fastf1_tools.constructor_championship_standings,
inputs=[
gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
gr.Dropdown(label="Constructor", choices=CONSTRUCTOR_NAMES)
],
outputs="text",
title="World Constructor Championship Standings",
description="Get the world constructor championship standings for a specific constructor"
)
iface_event_info = gr.Interface(
fn=fastf1_tools.get_event_info,
inputs=[
gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
gr.Textbox(label="Grand Prix", placeholder="Ex: Monaco", info="The name of the GP/country/location (Fuzzy matching supported) or round number"),
gr.Radio(["human", "LLM"], label="Display format", value="human")
],
outputs="text",
title="Event Info",
description="Get information about a specific Grand Prix event. Example: (2025,Monaco,human)"
)
iface_season_calendar = gr.Interface(
fn=fastf1_tools.get_season_calendar,
inputs=[
gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
],
outputs="text",
title="Season Calendar",
description="Get the season calendar for the given year"
)
iface_track_visualization = gr.Interface(
fn=fastf1_tools.track_visualization,
inputs=[
gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
gr.Textbox(label="Grand Prix", placeholder="Ex: Monaco", info="The name of the GP/country/location (Fuzzy matching supported) or round number"),
gr.Radio(["speed", "corners", "gear"], label="Visualization type", value="speed", info="What type of track visualization to generate"),
gr.Dropdown(label="Driver", choices=DRIVER_NAMES, info="Only applied for speed visualization. gear uses fastest lap during race.")
],
outputs="image",
title="Track Visualizations",
description="Get the track visualization for the given Grand Prix. Example: (2025,Monaco,speed,Leclerc)"
)
iface_session_results = gr.Interface(
fn=fastf1_tools.get_session_results,
inputs=[
gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
gr.Textbox(label="Grand Prix", placeholder="Ex: Monaco", info="The name of the GP/country/location (Fuzzy matching supported) or round number"),
gr.Dropdown([session_type for session_type in DROPDOWN_SESSION_TYPES if "practice" not in session_type], label="Session type", value="race", info="The session type to get results for. Dataframe's columns vary depending on session type.")
],
outputs=gr.Dataframe(
headers=None, # Let it infer from returned DataFrame
row_count=(0, "dynamic"), # Start empty, allow it to grow
col_count=(0, "dynamic") # Let columns adjust too
),
title="Session Results",
description="Get the session results for the given Grand Prix. Example: (2025,Monaco,qualifying)"
)
iface_driver_info = gr.Interface(
fn=fastf1_tools.get_driver_info,
inputs=[
gr.Dropdown(label="Driver", choices=DRIVER_NAMES)
],
outputs="text",
title="Driver Info",
description="Get background information about a specific driver"
)
iface_constructor_info = gr.Interface(
fn=fastf1_tools.get_constructor_info,
inputs=[
gr.Dropdown(label="Constructor", choices=CONSTRUCTOR_NAMES)
],
outputs="text",
title="Constructor Info",
description="Get background information about a specific constructor"
)
# Create your markdown-only tab using Blocks
with gr.Blocks() as markdown_tab:
gr.Markdown(MARKDOWN_INTRODUCTION)
# OpenF1 tools tab
def openf1_tools_tab():
with gr.Blocks() as openf1_tools_tab:
gr.Markdown(OPENF1_TOOL_DESCRIPTION)
with gr.Accordion("get_api_endpoints()", open=False):
btn = gr.Button("Get all endpoints")
output = gr.JSON()
def _get_api_endpoints():
return openf1_tools.get_api_endpoints()
btn.click(_get_api_endpoints, outputs=output)
with gr.Accordion("get_api_endpoint(endpoint)", open=False):
endpoint_in = gr.Textbox(label="Endpoint", placeholder="e.g. sessions")
btn = gr.Button("Get endpoint info")
output = gr.JSON()
def _get_api_endpoint(endpoint):
return openf1_tools.get_api_endpoint(endpoint)
btn.click(_get_api_endpoint, inputs=endpoint_in, outputs=output)
with gr.Accordion("get_endpoint_info(endpoint)", open=False):
endpoint_in = gr.Textbox(label="Endpoint", placeholder="e.g. sessions")
btn = gr.Button("Get endpoint details")
output = gr.JSON()
def _get_endpoint_info(endpoint):
return openf1_tools.get_endpoint_info(endpoint)
btn.click(_get_endpoint_info, inputs=endpoint_in, outputs=output)
with gr.Accordion("get_filter_info(filter_name)", open=False):
filter_in = gr.Textbox(label="Filter name", placeholder="e.g. driver_number")
btn = gr.Button("Get filter info")
output = gr.JSON()
def _get_filter_info(filter_name):
return openf1_tools.get_filter_info(filter_name)
btn.click(_get_filter_info, inputs=filter_in, outputs=output)
with gr.Accordion("get_filter_string(filter_name, filter_value, operator)", open=False):
filter_name = gr.Textbox(label="Filter name", placeholder="e.g. driver_number")
filter_value = gr.Textbox(label="Filter value", placeholder="e.g. 16")
operator = gr.Dropdown(label="Operator", choices=["=", ">", "<", ">=", "<="], value="=")
btn = gr.Button("Get filter string")
output = gr.Textbox(label="Filter string", info="Example: driver_number=16&")
def _get_filter_string(filter_name, filter_value, operator):
return openf1_tools.get_filter_string(filter_name, filter_value, operator)
btn.click(_get_filter_string, inputs=[filter_name, filter_value, operator], outputs=output)
with gr.Accordion("apply_filters(api_string, *filters)", open=False):
api_string = gr.Textbox(label="Base API string", placeholder="e.g. https://api.openf1.org/v1/sessions?")
filters = gr.Textbox(label="Filters (comma-separated)", placeholder="e.g. driver_number=16&,session_key=123&")
btn = gr.Button("Apply filters")
output = gr.Textbox(label="Full API string")
def _apply_filters(api_string, filters):
# Expect filters as comma-separated
filter_list = [f.strip() for f in filters.split(",") if f.strip()]
return openf1_tools.apply_filters(api_string, *filter_list)
btn.click(_apply_filters, inputs=[api_string, filters], outputs=output)
with gr.Accordion("send_request(api_string)", open=False):
with gr.Accordion("Example API requests (copy & paste into text box below)", open=False):
gr.Markdown(MARKDOWN_OPENF1_EXAMPLES)
api_string = gr.Textbox(label="Full API string", placeholder="e.g. https://api.openf1.org/v1/sessions?driver_number=16")
btn = gr.Button("Send API request")
output = gr.JSON()
def _send_request(api_string):
try:
return openf1_tools.send_request(api_string)
except Exception as e:
return {"error": str(e)}
btn.click(_send_request, inputs=api_string, outputs=output)
return openf1_tools_tab
# OpenF1 tabs
named_interfaces = {
"About": markdown_tab,
"Driver Championship Standings": iface_driver_championship_standings,
"Constructor Championship Standings": iface_constructor_championship_standings,
"Event Info": iface_event_info,
"Season Calendar": iface_season_calendar,
"Track Visualizations": iface_track_visualization,
"Session Results": iface_session_results,
"Driver Info": iface_driver_info,
"Constructor Info": iface_constructor_info,
"OpenF1 Tools": openf1_tools_tab(),
}
# Tab names and interfaces
tab_names = list(named_interfaces.keys())
interface_list = list(named_interfaces.values())
# Combine all the interfaces into a single TabbedInterface
gradio_server = gr.TabbedInterface(
interface_list,
tab_names=tab_names,
title="๐ Formula 1 MCP server ๐๏ธ"
)
# Launch the interface and MCP server
if __name__ == "__main__":
gradio_server.launch(mcp_server=True) |