{
"cells": [
{
"cell_type": "markdown",
"id": "md_0",
"metadata": {},
"source": [
"[](https://colab.research.google.com/github/oracle-devrel/oracle-ai-developer-hub/blob/main/notebooks/f1_miami_strategy_oracle_26ai.ipynb) [](https://www.oracle.com/database/) [](https://docs.fastf1.dev/) [](https://opensource.org/licenses/UPL)\n",
"\n",
"# \ud83c\udfce\ufe0f F1 Miami GP \u2014 Race Strategy Intelligence with Oracle AI Database 26ai\n",
"\n",
"**Author:** [Mariana Antaya](https://www.instagram.com/mar_antaya/) | **Notebook:** `f1_miami_strategy_oracle_26ai.ipynb`\n",
"\n",
"> *\"Miami 2026 is in 18 days. I wanted to answer a simple question: what tyre strategy actually wins here? Four years of data, four Oracle paradigms, one database.\"*\n",
"\n",
"---\n",
"\n",
"## What you'll learn\n",
"\n",
"This notebook walks through four Oracle AI Database 26ai paradigms using **real Formula 1 data** from the FastF1 API \u2014 no synthetic datasets, no toy examples.\n",
"\n",
"| # | Paradigm | Oracle Feature | F1 Question |\n",
"|---|---|---|---|\n",
"| 1 | **Relational SQL** | CTEs, window functions | What tyre strategy wins at Miami? (2022\u20132025) |\n",
"| 2 | **Hybrid Search** | `VECTOR_DISTANCE()` + `CONTAINS()` + RRF | Which past races *felt* like Miami? |\n",
"| 3 | **JSON Document** | `CLOB IS JSON` + `JSON_VALUE()` | What were the race conditions? |\n",
"| 4 | **Property Graph** | `GRAPH_TABLE()` | Which drivers share team history? |\n",
"| \u26a1 | **Convergent** | All four combined | Full race brief, one function call |\n",
"\n",
"### Why this matters for developers\n",
"\n",
"Answering these questions normally requires four completely separate databases \u2014 a relational DB for lap times, a vector store for semantic search, a graph DB for relationships, and a document store for unstructured metadata. **Oracle AI Database 26ai does all of it in one.** Same connection, same query language, no glue code.\n",
"\n",
"---\n",
"\n",
"## Prerequisites\n",
"\n",
"- [Docker Desktop](https://www.docker.com/products/docker-desktop/) installed and running\n",
"- Python 3.9+\n",
"- No API keys required \u2014 all embeddings run locally with `sentence-transformers`\n",
"\n",
"> **\u26a0\ufe0f Google Colab note:** Colab does not support Docker in its hosted runtime.\n",
"> To run this notebook in Colab, use the **Oracle Autonomous Database Free Tier**:\n",
"> 1. Sign up at [oracle.com/autonomous-database](https://www.oracle.com/autonomous-database/free-trial/)\n",
"> 2. Download your wallet zip file\n",
"> 3. Replace the `connect_oracle()` call with your wallet credentials\n",
">\n",
"> For the full local experience with Docker, run this notebook locally in VS Code or JupyterLab.\n"
]
},
{
"cell_type": "markdown",
"id": "md_1",
"metadata": {},
"source": [
"---\n",
"## Section 1: Environment Setup"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "code_2",
"metadata": {
"execution": {
"iopub.execute_input": "2026-04-15T10:41:42.463974Z",
"iopub.status.busy": "2026-04-15T10:41:42.463762Z",
"iopub.status.idle": "2026-04-15T10:41:42.985826Z",
"shell.execute_reply": "2026-04-15T10:41:42.985271Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u2705 All packages installed\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m26.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m26.0.1\u001b[0m\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49m/Users/marianaantaya/Downloads/f1-notebook/venv/bin/python3 -m pip install --upgrade pip\u001b[0m\n"
]
}
],
"source": [
"import subprocess, sys, sysconfig\n",
"\n",
"PACKAGES = [\n",
" \"oracledb==2.4.1\",\n",
" \"fastf1==3.4.0\",\n",
" \"sentence-transformers==3.0.1\",\n",
" \"pandas==2.2.2\",\n",
" \"numpy==1.26.4\",\n",
" \"plotly==5.22.0\",\n",
"]\n",
"\n",
"# Auto-detect if --break-system-packages is needed (PEP 668 / externally-managed)\n",
"cmd = [sys.executable, \"-m\", \"pip\", \"install\", \"-q\"]\n",
"marker = sysconfig.get_path(\"stdlib\")\n",
"if marker and \"site-packages\" not in (getattr(sys, \"prefix\", \"\") or \"\"):\n",
" # Check for EXTERNALLY-MANAGED marker (PEP 668)\n",
" import pathlib\n",
" ext_managed = any(\n",
" (pathlib.Path(p) / \"EXTERNALLY-MANAGED\").exists()\n",
" for p in [sysconfig.get_path(\"stdlib\"), sysconfig.get_path(\"platstdlib\")]\n",
" if p\n",
" )\n",
" if ext_managed:\n",
" cmd.append(\"--break-system-packages\")\n",
"subprocess.check_call(cmd + PACKAGES)\n",
"print(\"\u2705 All packages installed\")"
]
},
{
"cell_type": "markdown",
"id": "md_3",
"metadata": {},
"source": [
"---\n",
"### Start Oracle AI Database 26ai (Docker)\n",
"\n",
"The cell below automates the full Oracle lifecycle:\n",
"1. Pulls `ghcr.io/gvenzl/oracle-free:23.26.0` if not cached (~800MB, one-time)\n",
"2. Starts the container, waits until `FREEPDB1` is open read/write\n",
"3. Creates a dedicated `F1` user with `DB_DEVELOPER_ROLE` and Oracle Text privileges\n",
"\n",
"> **First pull:** ~2\u20133 minutes. Subsequent runs reuse the existing container and are instant."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "code_4",
"metadata": {
"execution": {
"iopub.execute_input": "2026-04-15T10:41:42.988009Z",
"iopub.status.busy": "2026-04-15T10:41:42.987889Z",
"iopub.status.idle": "2026-04-15T10:41:45.832961Z",
"shell.execute_reply": "2026-04-15T10:41:45.832322Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u2705 Container 'f1_oracle' already running\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u2705 Vector memory already 256M\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u2705 F1 user created with DB_DEVELOPER_ROLE + Oracle Text privileges\n"
]
}
],
"source": [
"import subprocess, time\n",
"\n",
"CONTAINER = \"f1_oracle\"\n",
"PORT = 1521\n",
"ADMIN_PWD = \"F1Oracle26ai!\"\n",
"F1_PWD = \"F1Str4tegy!\"\n",
"PDB = \"FREEPDB1\"\n",
"IMAGE = \"container-registry.oracle.com/database/free:latest\"\n",
"\n",
"def sh(*args, check=True):\n",
" return subprocess.run(list(args), capture_output=True, text=True, check=check)\n",
"\n",
"def oracle_is_open():\n",
" \"\"\"Check if FREEPDB1 is open by writing a temp SQL file \u2014 avoids shell escaping.\"\"\"\n",
" probe = sh(\n",
" \"docker\", \"exec\", CONTAINER, \"bash\", \"-c\",\n",
" \"cat > /tmp/check_pdb.sql << 'SQLEOF'\\n\"\n",
" \"SELECT OPEN_MODE FROM V$PDBS WHERE NAME='FREEPDB1';\\n\"\n",
" \"EXIT;\\n\"\n",
" \"SQLEOF\\n\"\n",
" \"sqlplus -s / as sysdba @/tmp/check_pdb.sql\",\n",
" check=False,\n",
" )\n",
" return probe.returncode == 0 and \"READ WRITE\" in probe.stdout.upper()\n",
"\n",
"def wait_ready(timeout_s=600, poll_s=12):\n",
" start = time.time()\n",
" while time.time() - start < timeout_s:\n",
" if oracle_is_open():\n",
" return True\n",
" print(f\" \u23f3 Waiting ({int(time.time()-start)}s)...\", end=\"\\r\")\n",
" time.sleep(poll_s)\n",
" raise TimeoutError(f\"Oracle did not open within {timeout_s}s\")\n",
"\n",
"def create_f1_user():\n",
" \"\"\"Create F1 user via heredoc SQL file \u2014 avoids all shell escaping issues.\"\"\"\n",
" sql_script = (\n",
" f\"cat > /tmp/create_f1.sql << 'SQLEOF'\\n\"\n",
" f\"ALTER SESSION SET CONTAINER={PDB};\\n\"\n",
" f\"BEGIN\\n\"\n",
" f\" EXECUTE IMMEDIATE 'DROP USER f1 CASCADE';\\n\"\n",
" f\"EXCEPTION WHEN OTHERS THEN NULL;\\n\"\n",
" f\"END;\\n\"\n",
" f\"/\\n\"\n",
" f\"CREATE USER f1 IDENTIFIED BY \\\"{F1_PWD}\\\"\\n\"\n",
" f\" DEFAULT TABLESPACE users QUOTA UNLIMITED ON users;\\n\"\n",
" f\"GRANT DB_DEVELOPER_ROLE TO f1;\\n\"\n",
" f\"GRANT CREATE SESSION TO f1;\\n\"\n",
" f\"GRANT EXECUTE ON CTXSYS.CTX_DDL TO f1;\\n\"\n",
" f\"EXIT;\\n\"\n",
" f\"SQLEOF\\n\"\n",
" f\"sqlplus -s \\\"sys/{ADMIN_PWD} as sysdba\\\" @/tmp/create_f1.sql\"\n",
" )\n",
" result = sh(\"docker\", \"exec\", CONTAINER, \"bash\", \"-c\", sql_script, check=False)\n",
" if \"Grant succeeded\" in result.stdout or \"User created\" in result.stdout:\n",
" print(\"\u2705 F1 user created with DB_DEVELOPER_ROLE + Oracle Text privileges\")\n",
" elif \"already exists\" in result.stdout.lower():\n",
" print(\"\u2705 F1 user already exists\")\n",
" else:\n",
" # Verify directly\n",
" verify = sh(\"docker\", \"exec\", CONTAINER, \"bash\", \"-c\",\n",
" f\"cat > /tmp/verify_f1.sql << 'SQLEOF'\\n\"\n",
" f\"ALTER SESSION SET CONTAINER={PDB};\\n\"\n",
" f\"SELECT USERNAME FROM DBA_USERS WHERE USERNAME='F1';\\n\"\n",
" f\"EXIT;\\n\"\n",
" f\"SQLEOF\\n\"\n",
" f\"sqlplus -s / as sysdba @/tmp/verify_f1.sql\",\n",
" check=False)\n",
" if \"F1\" in verify.stdout:\n",
" print(\"\u2705 F1 user verified\")\n",
" else:\n",
" print(f\"\u26a0\ufe0f User creation may have failed. Trying as sysdba locally...\")\n",
" # Fallback: connect as sysdba locally (no password needed)\n",
" sh(\"docker\", \"exec\", CONTAINER, \"bash\", \"-c\",\n",
" f\"cat > /tmp/create_f1_v2.sql << 'SQLEOF'\\n\"\n",
" f\"ALTER SESSION SET CONTAINER={PDB};\\n\"\n",
" f\"CREATE USER f1 IDENTIFIED BY \\\"{F1_PWD}\\\"\\n\"\n",
" f\" DEFAULT TABLESPACE users QUOTA UNLIMITED ON users;\\n\"\n",
" f\"GRANT DB_DEVELOPER_ROLE TO f1;\\n\"\n",
" f\"GRANT CREATE SESSION TO f1;\\n\"\n",
" f\"GRANT EXECUTE ON CTXSYS.CTX_DDL TO f1;\\n\"\n",
" f\"EXIT;\\n\"\n",
" f\"SQLEOF\\n\"\n",
" f\"sqlplus -s / as sysdba @/tmp/create_f1_v2.sql\",\n",
" check=False)\n",
" print(\"\u2705 F1 user created via sysdba fallback\")\n",
"\n",
"def configure_vector_memory(target_mb=256):\n",
" \"\"\"Enable HNSW vector indexes by allocating vector_memory_size in SGA.\"\"\"\n",
" check = sh(\"docker\", \"exec\", CONTAINER, \"bash\", \"-c\",\n",
" \"echo -e \\\"SHOW PARAMETER vector_memory_size;\\nEXIT;\\\" | sqlplus -s / as sysdba\",\n",
" check=False)\n",
" # Parse current value \u2014 look for a line like \"vector_memory_size ... 256M\"\n",
" for line in check.stdout.splitlines():\n",
" if \"vector_memory_size\" in line and f\"{target_mb}M\" in line:\n",
" print(f\"\u2705 Vector memory already {target_mb}M\")\n",
" return\n",
" print(f\"\u2699\ufe0f Setting vector_memory_size={target_mb}M (requires DB bounce)...\")\n",
" sh(\"docker\", \"exec\", CONTAINER, \"bash\", \"-c\",\n",
" f\"echo -e \\\"ALTER SYSTEM SET vector_memory_size={target_mb}M SCOPE=SPFILE;\\n\"\n",
" f\"SHUTDOWN IMMEDIATE;\\nSTARTUP;\\nEXIT;\\\" | sqlplus -s / as sysdba\",\n",
" check=False)\n",
" # Wait for DB to come back up after bounce\n",
" wait_ready()\n",
" print(f\"\u2705 Vector memory set to {target_mb}M \u2014 HNSW indexes enabled\")\n",
"\n",
"def setup_oracle():\n",
" ps = sh(\"docker\", \"ps\", \"--filter\", f\"name=^{CONTAINER}$\",\n",
" \"--format\", \"{{.Names}}\", check=False)\n",
" if CONTAINER in ps.stdout:\n",
" print(f\"\u2705 Container '{CONTAINER}' already running\")\n",
" configure_vector_memory()\n",
" create_f1_user()\n",
" return\n",
" ps_a = sh(\"docker\", \"ps\", \"-a\", \"--filter\", f\"name=^{CONTAINER}$\",\n",
" \"--format\", \"{{.Names}}\", check=False)\n",
" if CONTAINER in ps_a.stdout:\n",
" print(f\"\u25b6\ufe0f Starting existing container...\")\n",
" sh(\"docker\", \"start\", CONTAINER)\n",
" else:\n",
" print(f\"\ud83d\udc33 Starting {IMAGE} (first pull ~2-3 min)...\")\n",
" sh(\"docker\", \"run\", \"-d\",\n",
" \"--name\", CONTAINER,\n",
" \"-p\", f\"{PORT}:{PORT}\",\n",
" \"-e\", f\"ORACLE_PASSWORD={ADMIN_PWD}\",\n",
" IMAGE)\n",
" print(\"\u23f3 Waiting for FREEPDB1...\")\n",
" wait_ready()\n",
" print(\"\\n\u2705 Oracle AI Database 26ai is ready\")\n",
" configure_vector_memory()\n",
" create_f1_user()\n",
"\n",
"setup_oracle()\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "code_5",
"metadata": {
"execution": {
"iopub.execute_input": "2026-04-15T10:41:45.834658Z",
"iopub.status.busy": "2026-04-15T10:41:45.834555Z",
"iopub.status.idle": "2026-04-15T10:41:45.996277Z",
"shell.execute_reply": "2026-04-15T10:41:45.995706Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u2705 Connected: Oracle AI Database 26ai Free Release 23.26.1.0.0 - Develop, Learn, and Run for Free\n",
"Version 23.26.1.0.0\n"
]
}
],
"source": [
"import oracledb, time\n",
"\n",
"DSN = f\"127.0.0.1:{PORT}/{PDB}\"\n",
"\n",
"def connect_oracle(user=\"f1\", password=F1_PWD, dsn=DSN,\n",
" max_retries=5, retry_delay=8):\n",
" \"\"\"Connect with retry \u2014 Oracle may still be warming internal services.\"\"\"\n",
" for attempt in range(max_retries):\n",
" try:\n",
" conn = oracledb.connect(\n",
" user=user, password=password, dsn=dsn\n",
" )\n",
" cur = conn.cursor()\n",
" cur.execute(\"SELECT BANNER_FULL FROM V$VERSION\")\n",
" print(f\"\u2705 Connected: {cur.fetchone()[0]}\")\n",
" cur.close()\n",
" return conn\n",
" except Exception as e:\n",
" if attempt < max_retries - 1:\n",
" print(f\" Retry {attempt+1}/{max_retries}: {e}\")\n",
" time.sleep(retry_delay)\n",
" else:\n",
" raise RuntimeError(\n",
" f\"Could not connect after {max_retries} attempts. \"\n",
" \"Ensure the Docker setup cell above ran successfully first.\"\n",
" ) from e\n",
"\n",
"CONN = connect_oracle()"
]
},
{
"cell_type": "markdown",
"id": "md_6",
"metadata": {},
"source": [
"---\n",
"## Section 2: Schema \u2014 Four Paradigms in One Database\n",
"\n",
"Five tables covering all four Oracle AI Database 26ai paradigms.\n",
"\n",
"The critical column is `embedding VECTOR(384, FLOAT32)` in `race_events`.\n",
"This is a **native Oracle 26ai vector type** \u2014 no external vector database needed.\n",
"It lives in the same table as the message text, enabling hybrid search in a single SQL query.\n",
"\n",
"```\n",
"race_laps \u2192 Paradigm 1: Relational SQL\n",
"pit_stops \u2192 Paradigm 1: Relational SQL\n",
"race_events \u2192 Paradigm 2: Hybrid (VECTOR column + Oracle Text index + HNSW index)\n",
"race_metadata \u2192 Paradigm 3: JSON Document (CLOB IS JSON + JSON_VALUE)\n",
"driver_teams \u2192 Paradigm 4: Property Graph edge table\n",
"team_circuits \u2192 Paradigm 4: Property Graph edge table\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "code_7",
"metadata": {
"execution": {
"iopub.execute_input": "2026-04-15T10:41:45.998258Z",
"iopub.status.busy": "2026-04-15T10:41:45.998041Z",
"iopub.status.idle": "2026-04-15T10:41:47.694667Z",
"shell.execute_reply": "2026-04-15T10:41:47.693220Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u26a0\ufe0f ORA-42404: graph element table name DRIVER_TEAMS already defined\n",
"Help: https://docs.oracle.com/error-help/db/ora-42404/\n",
"\u2705 Schema created:\n",
" race_laps, pit_stops \u2192 Paradigm 1: Relational SQL\n",
" race_events \u2192 Paradigm 2: Hybrid (VECTOR + Oracle Text)\n",
" race_metadata \u2192 Paradigm 3: JSON Document\n",
" driver_career graph \u2192 Paradigm 4: Property Graph\n"
]
}
],
"source": [
"def run_ddl(conn, statements):\n",
" cur = conn.cursor()\n",
" for stmt in statements:\n",
" try:\n",
" cur.execute(stmt)\n",
" conn.commit()\n",
" except oracledb.DatabaseError as e:\n",
" code = e.args[0].code if e.args else 0\n",
" # Ignore: table does not exist (942), object does not exist (4043)\n",
" # 942: table does not exist 4043: object does not exist\n",
" # 439: feature not enabled 955: name already used\n",
" if code not in (942, 4043, 439, 955):\n",
" print(f\" \u26a0\ufe0f {str(e)[:120]}\")\n",
" cur.close()\n",
"\n",
"SCHEMA = [\n",
" # Drop existing objects cleanly\n",
" \"BEGIN EXECUTE IMMEDIATE 'DROP TABLE race_events'; EXCEPTION WHEN OTHERS THEN NULL; END;\",\n",
" \"BEGIN EXECUTE IMMEDIATE 'DROP TABLE pit_stops'; EXCEPTION WHEN OTHERS THEN NULL; END;\",\n",
" \"BEGIN EXECUTE IMMEDIATE 'DROP TABLE race_laps'; EXCEPTION WHEN OTHERS THEN NULL; END;\",\n",
" \"BEGIN EXECUTE IMMEDIATE 'DROP TABLE race_metadata'; EXCEPTION WHEN OTHERS THEN NULL; END;\",\n",
" \"BEGIN EXECUTE IMMEDIATE 'DROP TABLE team_circuits'; EXCEPTION WHEN OTHERS THEN NULL; END;\",\n",
" \"BEGIN EXECUTE IMMEDIATE 'DROP TABLE driver_teams'; EXCEPTION WHEN OTHERS THEN NULL; END;\",\n",
"\n",
" # \u2500\u2500 Paradigm 1: Relational \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
" \"\"\"CREATE TABLE race_laps (\n",
" id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,\n",
" season NUMBER(4) NOT NULL,\n",
" race_name VARCHAR2(100) NOT NULL,\n",
" circuit VARCHAR2(100),\n",
" driver VARCHAR2(10) NOT NULL,\n",
" team VARCHAR2(80),\n",
" lap_number NUMBER(3),\n",
" lap_time_s FLOAT,\n",
" position NUMBER(2),\n",
" compound VARCHAR2(12),\n",
" tyre_life NUMBER(3),\n",
" is_personal_best NUMBER(1) DEFAULT 0,\n",
" is_pit_in_lap NUMBER(1) DEFAULT 0, -- 1 if driver pitted this lap\n",
" is_pit_out_lap NUMBER(1) DEFAULT 0 -- 1 if driver exited pits this lap\n",
" )\"\"\",\n",
"\n",
" \"\"\"CREATE TABLE pit_stops (\n",
" id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,\n",
" season NUMBER(4) NOT NULL,\n",
" race_name VARCHAR2(100) NOT NULL,\n",
" circuit VARCHAR2(100),\n",
" driver VARCHAR2(10) NOT NULL,\n",
" team VARCHAR2(80),\n",
" stop_number NUMBER(2),\n",
" lap_in NUMBER(3), -- lap on which driver entered pits\n",
" compound_in VARCHAR2(12), -- tyre fitted AFTER this stop\n",
" compound_out VARCHAR2(12), -- tyre removed AT this stop\n",
" stop_duration_s FLOAT -- stationary time (seconds)\n",
" )\"\"\",\n",
"\n",
" # \u2500\u2500 Paradigm 2: Hybrid \u2014 Vector + Full-Text \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
" # VECTOR(384, FLOAT32): native Oracle 26ai vector column\n",
" # Oracle Text index on .message: enables CONTAINS() keyword search\n",
" # HNSW vector index on .embedding: enables VECTOR_DISTANCE() semantic search\n",
" # Both on the SAME table \u2014 the converged database advantage\n",
" \"\"\"CREATE TABLE race_events (\n",
" id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,\n",
" season NUMBER(4) NOT NULL,\n",
" race_name VARCHAR2(100) NOT NULL,\n",
" circuit VARCHAR2(100),\n",
" lap_number NUMBER(3),\n",
" event_type VARCHAR2(50),\n",
" message VARCHAR2(1000) NOT NULL,\n",
" embedding VECTOR(384, FLOAT32)\n",
" )\"\"\",\n",
"\n",
" # \u2500\u2500 Paradigm 3: JSON Document \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
" \"\"\"CREATE TABLE race_metadata (\n",
" id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,\n",
" season NUMBER(4) NOT NULL,\n",
" race_name VARCHAR2(100) NOT NULL,\n",
" circuit VARCHAR2(100),\n",
" race_context CLOB NOT NULL,\n",
" CONSTRAINT ck_meta_json CHECK (race_context IS JSON)\n",
" )\"\"\",\n",
"\n",
" # \u2500\u2500 Paradigm 4: Property Graph edge tables \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
" \"\"\"CREATE TABLE driver_teams (\n",
" id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,\n",
" driver VARCHAR2(10) NOT NULL,\n",
" team VARCHAR2(80) NOT NULL,\n",
" season NUMBER(4) NOT NULL,\n",
" wins NUMBER(3) DEFAULT 0,\n",
" podiums NUMBER(3) DEFAULT 0,\n",
" CONSTRAINT uq_dt UNIQUE (driver, team, season)\n",
" )\"\"\",\n",
" \"\"\"CREATE TABLE team_circuits (\n",
" id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,\n",
" team VARCHAR2(80) NOT NULL,\n",
" circuit VARCHAR2(100) NOT NULL,\n",
" season NUMBER(4) NOT NULL,\n",
" best_finish NUMBER(2) DEFAULT 20,\n",
" CONSTRAINT uq_tc UNIQUE (team, circuit, season)\n",
" )\"\"\",\n",
"\n",
" # Performance indexes\n",
" \"CREATE INDEX idx_laps_race ON race_laps(season, race_name)\",\n",
" \"CREATE INDEX idx_laps_driver ON race_laps(driver, season)\",\n",
" \"CREATE INDEX idx_pits_race ON pit_stops(season, race_name)\",\n",
" \"CREATE INDEX idx_events_race ON race_events(season, race_name)\",\n",
"\n",
" # Oracle Text index \u2014 enables CONTAINS() keyword search on message column\n",
" \"\"\"CREATE INDEX idx_events_text ON race_events(message)\n",
" INDEXTYPE IS CTXSYS.CONTEXT\n",
" PARAMETERS ('SYNC (ON COMMIT)')\"\"\",\n",
"\n",
" # HNSW approximate nearest-neighbour vector index\n",
" # Same algorithm as Pinecone/Chroma \u2014 running natively inside Oracle\n",
" # TARGET ACCURACY 95 = 95% recall guarantee at query time\n",
" \"\"\"CREATE VECTOR INDEX idx_events_vec ON race_events(embedding)\n",
" ORGANIZATION INMEMORY NEIGHBOR GRAPH\n",
" DISTANCE COSINE\n",
" WITH TARGET ACCURACY 95\"\"\",\n",
"\n",
" # SQL Property Graph \u2014 driver career network\n",
" # Enables GRAPH_TABLE() traversal without Neo4j\n",
" \"\"\"CREATE PROPERTY GRAPH driver_career\n",
" VERTEX TABLES (\n",
" driver_teams\n",
" KEY (driver) LABEL Driver\n",
" PROPERTIES (driver, wins, podiums),\n",
" driver_teams AS team_vertex\n",
" KEY (team) LABEL Team\n",
" PROPERTIES (team),\n",
" team_circuits AS circuit_vertex\n",
" KEY (circuit) LABEL Circuit\n",
" PROPERTIES (circuit)\n",
" )\n",
" EDGE TABLES (\n",
" driver_teams\n",
" KEY (id)\n",
" SOURCE KEY (driver) REFERENCES driver_teams(driver)\n",
" DESTINATION KEY (team) REFERENCES driver_teams(team)\n",
" LABEL DROVE_FOR PROPERTIES (season, wins),\n",
" team_circuits\n",
" KEY (id)\n",
" SOURCE KEY (team) REFERENCES driver_teams(team)\n",
" DESTINATION KEY (circuit) REFERENCES team_circuits(circuit)\n",
" LABEL RACED_AT PROPERTIES (season, best_finish)\n",
" )\"\"\",\n",
"]\n",
"\n",
"run_ddl(CONN, SCHEMA)\n",
"print(\"\u2705 Schema created:\")\n",
"print(\" race_laps, pit_stops \u2192 Paradigm 1: Relational SQL\")\n",
"print(\" race_events \u2192 Paradigm 2: Hybrid (VECTOR + Oracle Text)\")\n",
"print(\" race_metadata \u2192 Paradigm 3: JSON Document\")\n",
"print(\" driver_career graph \u2192 Paradigm 4: Property Graph\")"
]
},
{
"cell_type": "markdown",
"id": "md_8",
"metadata": {},
"source": [
"---\n",
"## Section 3: Embeddings\n",
"\n",
"`all-MiniLM-L6-v2` encodes text as 384-dimensional float32 vectors.\n",
"Sentences with similar *meaning* land close together in vector space \u2014\n",
"so `\"SAFETY CAR DEPLOYED LAP 47\"` and `\"VSC CALLED LAP 51\"` are nearby\n",
"even though the words differ completely.\n",
"\n",
"Oracle stores these vectors natively in the `VECTOR(384, FLOAT32)` column.\n",
"No serialisation, no external service \u2014 the `oracledb` driver accepts\n",
"`array.array('f', ...)` directly as a bind variable."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "code_9",
"metadata": {
"execution": {
"iopub.execute_input": "2026-04-15T10:41:47.698584Z",
"iopub.status.busy": "2026-04-15T10:41:47.698271Z",
"iopub.status.idle": "2026-04-15T10:41:54.162893Z",
"shell.execute_reply": "2026-04-15T10:41:54.162231Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/marianaantaya/Downloads/f1-notebook/venv/lib/python3.12/site-packages/sentence_transformers/cross_encoder/CrossEncoder.py:11: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
" from tqdm.autonotebook import tqdm, trange\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u23f3 Loading all-MiniLM-L6-v2 (downloads once, ~90MB)...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u2705 Embedding model ready \u2014 384 dimensions, runs locally\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Sample: 384 dims | first 3 values: [0.0019892840646207333, 0.07707614451646805, -0.0509980171918869]\n"
]
}
],
"source": [
"import array\n",
"from sentence_transformers import SentenceTransformer\n",
"\n",
"print(\"\u23f3 Loading all-MiniLM-L6-v2 (downloads once, ~90MB)...\")\n",
"_MODEL = SentenceTransformer(\"all-MiniLM-L6-v2\")\n",
"print(\"\u2705 Embedding model ready \u2014 384 dimensions, runs locally\")\n",
"\n",
"def to_vec(text: str) -> array.array:\n",
" \"\"\"Encode text to Oracle-compatible VECTOR(384, FLOAT32).\"\"\"\n",
" v = _MODEL.encode(text, normalize_embeddings=True)\n",
" return array.array(\"f\", v.tolist())\n",
"\n",
"sample = to_vec(\"Safety car deployed lap 47\")\n",
"print(f\"Sample: {len(sample)} dims | first 3 values: {list(sample[:3])}\")"
]
},
{
"cell_type": "markdown",
"id": "md_10",
"metadata": {},
"source": [
"---\n",
"## Section 4: Data Ingestion \u2014 FastF1 \u2192 Oracle AI Database 26ai\n",
"\n",
"FastF1 pulls directly from F1's official live timing service.\n",
"For each race session we populate all four paradigm tables.\n",
"\n",
"### Fix note \u2014 pit stop detection\n",
"A common mistake is inferring pit stops from compound *changes* between laps.\n",
"This is unreliable because FastF1 sometimes fills in missing compound data,\n",
"creating false transitions.\n",
"\n",
"**This notebook uses `PitInTime` and `PitOutTime` columns** \u2014 FastF1's actual\n",
"pit stop timestamps \u2014 to detect real pit laps. A lap where `PitInTime` is not NaT\n",
"is a genuine pit stop lap. This is how you'd do it in a real race engineering context."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "code_11",
"metadata": {
"execution": {
"iopub.execute_input": "2026-04-15T10:41:54.165035Z",
"iopub.status.busy": "2026-04-15T10:41:54.164541Z",
"iopub.status.idle": "2026-04-15T10:41:54.271046Z",
"shell.execute_reply": "2026-04-15T10:41:54.270506Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u2705 FastF1 cache enabled at ./f1_cache\n",
"\u2705 Ingestion function ready\n"
]
}
],
"source": [
"import fastf1\n",
"import pandas as pd\n",
"import numpy as np\n",
"import json, os, warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n",
"os.makedirs(\"./f1_cache\", exist_ok=True)\n",
"fastf1.Cache.enable_cache(\"./f1_cache\")\n",
"print(\"\u2705 FastF1 cache enabled at ./f1_cache\")\n",
"\n",
"def ingest_race(season: int, race_name: str, conn) -> dict:\n",
" \"\"\"\n",
" Load one F1 race into Oracle AI Database 26ai.\n",
" Populates all four paradigm tables.\n",
"\n",
" Pit stop detection uses PitInTime/PitOutTime timestamps from FastF1,\n",
" not compound transitions \u2014 the correct and reliable approach.\n",
" \"\"\"\n",
" print(f\"\\n\ud83d\udce1 {season} {race_name}...\")\n",
" try:\n",
" sess = fastf1.get_session(season, race_name, \"R\")\n",
" sess.load(laps=True, weather=True, telemetry=False, messages=True)\n",
" except Exception as e:\n",
" print(f\" \u26a0\ufe0f Cannot load: {e}\")\n",
" return {}\n",
"\n",
" circuit = sess.event.get(\"Location\", race_name)\n",
" laps_df = sess.laps.copy()\n",
" cur = conn.cursor()\n",
" counts = {\"laps\": 0, \"pits\": 0, \"events\": 0}\n",
"\n",
" # \u2500\u2500 race_laps (Paradigm 1: Relational) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
" # Drop laps with no useful timing data\n",
" valid = laps_df.dropna(subset=[\"LapTime\"])\n",
" lap_rows = []\n",
" for _, lap in valid.iterrows():\n",
" try:\n",
" lt = lap[\"LapTime\"].total_seconds()\n",
" if lt < 30 or lt > 600: # discard clearly wrong laps\n",
" continue\n",
" compound = str(lap.get(\"Compound\", \"\")).upper()\n",
" if compound not in (\"SOFT\",\"MEDIUM\",\"HARD\",\"INTERMEDIATE\",\"WET\"):\n",
" compound = \"UNKNOWN\"\n",
" # Detect pit laps from FastF1's actual pit timestamps\n",
" is_pit_in = 1 if pd.notna(lap.get(\"PitInTime\")) else 0\n",
" is_pit_out = 1 if pd.notna(lap.get(\"PitOutTime\")) else 0\n",
" lap_rows.append((\n",
" int(season), str(race_name), str(circuit),\n",
" str(lap[\"Driver\"]),\n",
" str(lap.get(\"Team\",\"Unknown\"))[:80],\n",
" int(lap[\"LapNumber\"]),\n",
" round(float(lt), 3),\n",
" int(lap[\"Position\"]) if pd.notna(lap.get(\"Position\")) else None,\n",
" compound,\n",
" int(lap[\"TyreLife\"]) if pd.notna(lap.get(\"TyreLife\")) else None,\n",
" 1 if lap.get(\"IsPersonalBest\") else 0,\n",
" is_pit_in,\n",
" is_pit_out,\n",
" ))\n",
" except Exception:\n",
" continue\n",
"\n",
" if lap_rows:\n",
" cur.executemany(\n",
" \"\"\"INSERT INTO race_laps\n",
" (season,race_name,circuit,driver,team,lap_number,lap_time_s,\n",
" position,compound,tyre_life,is_personal_best,is_pit_in_lap,is_pit_out_lap)\n",
" VALUES(:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13)\"\"\",\n",
" lap_rows)\n",
" counts[\"laps\"] = len(lap_rows)\n",
"\n",
" # \u2500\u2500 pit_stops (Paradigm 1: Relational) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
" # Use PitInTime/PitOutTime \u2014 the correct FastF1 approach\n",
" # PitInTime: moment wheels crossed the pit entry line\n",
" # PitOutTime: moment car left the pit box\n",
" # Stop duration = PitOutTime - PitInTime (stationary time only)\n",
" for driver in laps_df[\"Driver\"].unique():\n",
" dl = laps_df[laps_df[\"Driver\"] == driver].sort_values(\"LapNumber\").copy()\n",
" stop_num = 1\n",
" for _, lap in dl.iterrows():\n",
" # Only process laps where driver actually pitted\n",
" if not pd.notna(lap.get(\"PitInTime\")):\n",
" continue\n",
" # Tyre fitted before this stint (compound on the pit-out lap)\n",
" out_lap = dl[dl[\"LapNumber\"] == lap[\"LapNumber\"] + 1]\n",
" compound_in = None\n",
" compound_out = str(lap.get(\"Compound\",\"\")).upper() or None\n",
" if len(out_lap) > 0:\n",
" c = str(out_lap.iloc[0].get(\"Compound\",\"\")).upper()\n",
" if c in (\"SOFT\",\"MEDIUM\",\"HARD\",\"INTERMEDIATE\",\"WET\"):\n",
" compound_in = c\n",
" if compound_out not in (\"SOFT\",\"MEDIUM\",\"HARD\",\"INTERMEDIATE\",\"WET\"):\n",
" compound_out = None\n",
"\n",
" # Calculate stop duration if timestamps available\n",
" stop_dur = None\n",
" if pd.notna(lap.get(\"PitInTime\")) and pd.notna(lap.get(\"PitOutTime\")):\n",
" try:\n",
" stop_dur = round(\n",
" (lap[\"PitOutTime\"] - lap[\"PitInTime\"]).total_seconds(), 2\n",
" )\n",
" # Sanity check: real pit stops are 2-60 seconds\n",
" if stop_dur < 1 or stop_dur > 120:\n",
" stop_dur = None\n",
" except Exception:\n",
" stop_dur = None\n",
"\n",
" try:\n",
" cur.execute(\n",
" \"\"\"INSERT INTO pit_stops\n",
" (season,race_name,circuit,driver,team,stop_number,\n",
" lap_in,compound_in,compound_out,stop_duration_s)\n",
" VALUES(:1,:2,:3,:4,:5,:6,:7,:8,:9,:10)\"\"\",\n",
" (int(season), str(race_name), str(circuit),\n",
" str(driver), str(lap.get(\"Team\",\"Unknown\"))[:80],\n",
" stop_num, int(lap[\"LapNumber\"]),\n",
" compound_in, compound_out, stop_dur))\n",
" stop_num += 1\n",
" counts[\"pits\"] += 1\n",
" except Exception:\n",
" continue\n",
"\n",
" # \u2500\u2500 race_events (Paradigm 2: Hybrid \u2014 Vector + Full-Text) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
" # Race control messages: stored as text AND embedded as 384-dim vectors.\n",
" # Oracle Text index \u2192 CONTAINS() keyword search\n",
" # HNSW vector index \u2192 VECTOR_DISTANCE() semantic search\n",
" # Both on the same column in the same table.\n",
" if hasattr(sess, \"race_control_messages\") and sess.race_control_messages is not None:\n",
" for _, msg in sess.race_control_messages.iterrows():\n",
" txt = str(msg.get(\"Message\",\"\")).strip()\n",
" if not txt or txt.lower() == \"nan\":\n",
" continue\n",
" lap_n = int(msg[\"Lap\"]) if pd.notna(msg.get(\"Lap\")) else 0\n",
" etype = str(msg.get(\"Category\",\"OTHER\"))\n",
" # Contextual embedding includes race name + lap for richer semantics\n",
" emb = to_vec(f\"{etype}: {txt} (lap {lap_n}, {race_name} {season})\")\n",
" cur.execute(\n",
" \"\"\"INSERT INTO race_events\n",
" (season,race_name,circuit,lap_number,event_type,message,embedding)\n",
" VALUES(:1,:2,:3,:4,:5,:6,:7)\"\"\",\n",
" (int(season), str(race_name), str(circuit),\n",
" lap_n, etype, txt[:1000], emb))\n",
" counts[\"events\"] += 1\n",
"\n",
" # \u2500\u2500 race_metadata (Paradigm 3: JSON Document) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
" try:\n",
" wdf = sess.weather_data\n",
" meta = {\n",
" \"circuit\": circuit,\n",
" \"season\": season,\n",
" \"race_name\": race_name,\n",
" \"total_laps\": int(valid[\"LapNumber\"].max()) if len(valid) else 0,\n",
" \"drivers\": int(laps_df[\"Driver\"].nunique()),\n",
" \"rcm_count\": counts[\"events\"],\n",
" \"weather\": {\n",
" \"avg_air_temp_c\": round(float(wdf[\"AirTemp\"].mean()), 1) if len(wdf) else None,\n",
" \"avg_track_temp_c\": round(float(wdf[\"TrackTemp\"].mean()), 1) if len(wdf) else None,\n",
" \"rainfall\": bool(wdf[\"Rainfall\"].any()) if len(wdf) else False,\n",
" \"avg_humidity_pct\": round(float(wdf[\"Humidity\"].mean()), 1) if len(wdf) else None,\n",
" },\n",
" }\n",
" cur.execute(\n",
" \"INSERT INTO race_metadata (season,race_name,circuit,race_context) VALUES(:1,:2,:3,:4)\",\n",
" (int(season), str(race_name), str(circuit), json.dumps(meta)))\n",
" except Exception as e:\n",
" print(f\" \u26a0\ufe0f Metadata: {e}\")\n",
"\n",
" # \u2500\u2500 driver_teams + team_circuits (Paradigm 4: Graph edges) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
" final = valid.sort_values(\"LapNumber\", ascending=False).drop_duplicates(\"Driver\")\n",
" for _, row in final.iterrows():\n",
" try:\n",
" pos = int(row.get(\"Position\",99)) if pd.notna(row.get(\"Position\")) else 99\n",
" wins = 1 if pos == 1 else 0\n",
" podiums = 1 if pos <= 3 else 0\n",
" team = str(row.get(\"Team\",\"Unknown\"))[:80]\n",
" cur.execute(\n",
" \"\"\"MERGE INTO driver_teams dt\n",
" USING (SELECT :drv d,:tm t,:ssn s FROM DUAL) src\n",
" ON (dt.driver=src.d AND dt.team=src.t AND dt.season=src.s)\n",
" WHEN NOT MATCHED THEN\n",
" INSERT (driver,team,season,wins,podiums) VALUES(src.d,src.t,src.s,:w,:p)\n",
" WHEN MATCHED THEN\n",
" UPDATE SET wins=dt.wins+:w, podiums=dt.podiums+:p\"\"\",\n",
" {\"drv\": str(row[\"Driver\"]), \"tm\": team, \"ssn\": int(season), \"w\": wins, \"p\": podiums})\n",
" cur.execute(\n",
" \"\"\"MERGE INTO team_circuits tc\n",
" USING (SELECT :tm t,:cir c,:ssn s FROM DUAL) src\n",
" ON (tc.team=src.t AND tc.circuit=src.c AND tc.season=src.s)\n",
" WHEN NOT MATCHED THEN\n",
" INSERT (team,circuit,season,best_finish) VALUES(src.t,src.c,src.s,:bf)\n",
" WHEN MATCHED THEN\n",
" UPDATE SET best_finish=LEAST(tc.best_finish,:bf)\"\"\",\n",
" {\"tm\": team, \"cir\": str(circuit), \"ssn\": int(season), \"bf\": pos})\n",
" except Exception:\n",
" continue\n",
"\n",
" conn.commit()\n",
" cur.close()\n",
" print(f\" \u2705 {counts['laps']:,} laps | {counts['pits']} pit stops \"\n",
" f\"(PitInTime-verified) | {counts['events']} events embedded\")\n",
" return counts\n",
"\n",
"print(\"\u2705 Ingestion function ready\")\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "code_12",
"metadata": {
"execution": {
"iopub.execute_input": "2026-04-15T10:41:54.272340Z",
"iopub.status.busy": "2026-04-15T10:41:54.272229Z",
"iopub.status.idle": "2026-04-15T10:43:20.117235Z",
"shell.execute_reply": "2026-04-15T10:43:20.116469Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\ud83d\udce1 2022 Miami...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Miami Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['16', '55', '1', '11', '77', '44', '10', '4', '22', '18', '14', '63', '5', '3', '47', '20', '24', '23', '6', '31']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Miami Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,002 laps | 29 pit stops (PitInTime-verified) | 76 events embedded\n",
"\n",
"\ud83d\udce1 2023 Miami...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['11', '14', '55', '20', '10', '63', '16', '31', '1', '77', '23', '27', '44', '24', '21', '4', '22', '18', '81', '2']\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,118 laps | 20 pit stops (PitInTime-verified) | 38 events embedded\n",
"\n",
"\ud83d\udce1 2024 Miami...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Miami Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '16', '55', '11', '4', '81', '63', '44', '27', '22', '18', '10', '31', '23', '14', '77', '2', '20', '24', '3']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Miami Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for session_info. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching session info data...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,086 laps | 28 pit stops (PitInTime-verified) | 75 events embedded\n",
"\n",
"\ud83d\udce1 2025 Miami...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for driver_info. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching driver list...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for session_status_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching session status data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for lap_count. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching lap count data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for track_status_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching track status data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for _extended_timing_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tParsing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for timing_app_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching timing app data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for weather_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching weather data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for race_control_messages. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching race control messages...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '4', '12', '81', '63', '55', '23', '16', '31', '22', '6', '44', '5', '7', '30', '27', '14', '18', '87', '10']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Bahrain Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for session_info. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching session info data...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 983 laps | 19 pit stops (PitInTime-verified) | 77 events embedded\n",
"\n",
"\ud83d\udce1 2025 Bahrain...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for driver_info. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching driver list...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for session_status_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching session status data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for lap_count. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching lap count data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for track_status_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching track status data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for _extended_timing_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tParsing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for timing_app_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching timing app data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tDriver 63: Lap timing integrity check failed for 3 lap(s)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for weather_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching weather data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for race_control_messages. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching race control messages...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['81', '16', '63', '10', '12', '4', '1', '55', '44', '22', '7', '6', '14', '31', '23', '27', '30', '5', '18', '87']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Saudi Arabian Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for session_info. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching session info data...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,094 laps | 43 pit stops (PitInTime-verified) | 91 events embedded\n",
"\n",
"\ud83d\udce1 2025 Saudi Arabia...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for driver_info. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching driver list...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for session_status_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching session status data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for lap_count. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching lap count data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for track_status_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching track status data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for _extended_timing_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tParsing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api WARNING \tSkipping lap alignment (no suitable lap)!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for timing_app_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching timing app data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for weather_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching weather data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for race_control_messages. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching race control messages...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '81', '63', '16', '12', '55', '44', '22', '10', '4', '23', '30', '14', '6', '87', '18', '7', '27', '31', '5']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Japanese Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for session_info. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching session info data...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 842 laps | 20 pit stops (PitInTime-verified) | 65 events embedded\n",
"\n",
"\ud83d\udce1 2025 Japan...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for driver_info. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching driver list...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for session_status_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching session status data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for lap_count. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching lap count data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for track_status_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching track status data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for _extended_timing_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tParsing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for timing_app_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching timing app data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for weather_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching weather data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for race_control_messages. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching race control messages...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '4', '81', '16', '63', '12', '6', '44', '23', '87', '10', '14', '30', '22', '55', '27', '5', '31', '7', '18']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Chinese Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for session_info. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching session info data...\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,039 laps | 21 pit stops (PitInTime-verified) | 23 events embedded\n",
"\n",
"\ud83d\udce1 2025 China...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for driver_info. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching driver list...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for session_status_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching session status data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for lap_count. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching lap count data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for track_status_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching track status data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for _extended_timing_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tParsing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for timing_app_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching timing app data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for weather_data. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching weather data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tNo cached data found for race_control_messages. Loading data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"_api INFO \tFetching race control messages...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tData has been written to cache!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['81', '63', '4', '1', '44', '16', '6', '12', '22', '23', '31', '27', '14', '18', '55', '10', '87', '7', '5', '30']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Bahrain Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,045 laps | 26 pit stops (PitInTime-verified) | 56 events embedded\n",
"\n",
"\ud83d\udce1 2024 Bahrain...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '16', '63', '55', '11', '14', '4', '81', '44', '27', '22', '18', '23', '3', '20', '77', '24', '2', '31', '10']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Saudi Arabian Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,107 laps | 43 pit stops (PitInTime-verified) | 69 events embedded\n",
"\n",
"\ud83d\udce1 2024 Saudi Arabia...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '16', '11', '14', '81', '4', '63', '44', '22', '18', '38', '23', '20', '3', '27', '77', '31', '10', '2', '24']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Japanese Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 853 laps | 20 pit stops (PitInTime-verified) | 66 events embedded\n",
"\n",
"\ud83d\udce1 2024 Japan...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '11', '4', '55', '14', '81', '44', '16', '63', '22', '3', '27', '77', '23', '31', '18', '10', '20', '2', '24']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Chinese Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 858 laps | 55 pit stops (PitInTime-verified) | 66 events embedded\n",
"\n",
"\ud83d\udce1 2024 China...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '11', '14', '4', '81', '16', '55', '63', '27', '77', '18', '3', '31', '23', '10', '24', '20', '44', '22', '2']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Monaco Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 987 laps | 41 pit stops (PitInTime-verified) | 56 events embedded\n",
"\n",
"\ud83d\udce1 2024 Monaco...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['16', '81', '55', '4', '63', '1', '44', '22', '23', '10', '31', '3', '18', '14', '2', '11', '77', '24', '27', '20']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Canadian Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,210 laps | 23 pit stops (PitInTime-verified) | 118 events embedded\n",
"\n",
"\ud83d\udce1 2024 Canada...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['63', '1', '4', '81', '3', '14', '44', '22', '18', '23', '16', '55', '2', '20', '10', '11', '27', '31', '77', '24']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Spanish Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,247 laps | 45 pit stops (PitInTime-verified) | 128 events embedded\n",
"\n",
"\ud83d\udce1 2024 Spain...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['4', '1', '44', '63', '16', '55', '10', '31', '81', '14', '11', '77', '27', '18', '24', '20', '22', '3', '2', '23']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Austrian Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,290 laps | 42 pit stops (PitInTime-verified) | 105 events embedded\n",
"\n",
"\ud83d\udce1 2024 Austria...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '4', '63', '55', '44', '16', '81', '11', '27', '31', '3', '20', '10', '22', '14', '23', '18', '77', '2', '24']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Las Vegas Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,385 laps | 46 pit stops (PitInTime-verified) | 124 events embedded\n",
"\n",
"\ud83d\udce1 2023 Las Vegas...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['16', '1', '63', '10', '23', '2', '77', '20', '14', '44', '11', '55', '27', '3', '4', '31', '24', '81', '18', '22']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Monaco Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 841 laps | 31 pit stops (PitInTime-verified) | 73 events embedded\n",
"\n",
"\ud83d\udce1 2023 Monaco...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '14', '31', '55', '44', '16', '10', '63', '22', '4', '81', '21', '23', '18', '77', '2', '20', '27', '24', '11']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Singapore Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,492 laps | 38 pit stops (PitInTime-verified) | 242 events embedded\n",
"\n",
"\ud83d\udce1 2023 Singapore...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 19 drivers: ['55', '63', '16', '4', '44', '20', '14', '31', '27', '40', '1', '10', '11', '23', '22', '77', '81', '2', '24']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Abu Dhabi Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,044 laps | 25 pit stops (PitInTime-verified) | 74 events embedded\n",
"\n",
"\ud83d\udce1 2023 Abu Dhabi...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '16', '81', '63', '4', '22', '14', '27', '11', '10', '44', '31', '18', '23', '3', '55', '20', '77', '24', '2']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Monaco Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,137 laps | 38 pit stops (PitInTime-verified) | 65 events embedded\n",
"\n",
"\ud83d\udce1 2022 Monaco...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['16', '55', '11', '1', '4', '63', '14', '44', '5', '31', '22', '77', '20', '3', '47', '23', '10', '18', '6', '24']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Abu Dhabi Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,133 laps | 55 pit stops (PitInTime-verified) | 168 events embedded\n",
"\n",
"\ud83d\udce1 2022 Abu Dhabi...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 20 drivers: ['1', '11', '16', '55', '44', '63', '4', '31', '5', '14', '22', '47', '3', '18', '24', '20', '10', '77', '23', '6']\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tLoading data for Abu Dhabi Grand Prix - Race [v3.4.0]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_info\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for driver_info\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 1,097 laps | 34 pit stops (PitInTime-verified) | 90 events embedded\n",
"\n",
"\ud83d\udce1 2021 Abu Dhabi...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to load result data from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core WARNING \tNo result data for this session available on Ergast! (This is expected for recent sessions)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for session_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for lap_count\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for track_status_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for _extended_timing_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for timing_app_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tProcessing timing data...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"logger WARNING \tFailed to add first lap time from Ergast!\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for weather_data\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"req INFO \tUsing cached data for race_control_messages\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"core INFO \tFinished loading data for 19 drivers: ['33', '44', '4', '11', '55', '77', '16', '22', '31', '3', '14', '10', '18', '99', '5', '6', '63', '7', '47']\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u2705 970 laps | 32 pit stops (PitInTime-verified) | 74 events embedded\n",
"\n",
"\ud83c\udfc1 Done: 24,860 laps | 774 pit stops | 2019 race events embedded as VECTOR(384, FLOAT32)\n"
]
}
],
"source": [
"# Load races into Oracle AI Database 26ai\n",
"# Miami 2022-2025: four years of history for the 2026 prediction\n",
"# 2025 season races: builds current team baselines for overperformance\n",
"# Cross-season circuits: enriches hybrid search comparison pool\n",
"\n",
"RACES = [\n",
" # Miami \u2014 four years of history for the 2026 strategy prediction\n",
" (2022, \"Miami\"),\n",
" (2023, \"Miami\"),\n",
" (2024, \"Miami\"),\n",
" (2025, \"Miami\"),\n",
" # 2025 season races \u2014 critical for current team baselines\n",
" (2025, \"Bahrain\"),\n",
" (2025, \"Saudi Arabia\"),\n",
" (2025, \"Japan\"),\n",
" (2025, \"China\"),\n",
" # 2024 season races \u2014 additional baseline depth\n",
" (2024, \"Bahrain\"),\n",
" (2024, \"Saudi Arabia\"),\n",
" (2024, \"Japan\"),\n",
" (2024, \"China\"),\n",
" (2024, \"Monaco\"),\n",
" (2024, \"Canada\"),\n",
" (2024, \"Spain\"),\n",
" (2024, \"Austria\"),\n",
" # Comparison circuits for hybrid search\n",
" (2023, \"Las Vegas\"),\n",
" (2023, \"Monaco\"),\n",
" (2023, \"Singapore\"),\n",
" (2023, \"Abu Dhabi\"),\n",
" (2022, \"Monaco\"),\n",
" (2022, \"Abu Dhabi\"),\n",
" (2021, \"Abu Dhabi\"),\n",
"]\n",
"\n",
"total = {\"laps\": 0, \"pits\": 0, \"events\": 0}\n",
"for season, race in RACES:\n",
" counts = ingest_race(season, race, CONN)\n",
" for k in total:\n",
" total[k] += counts.get(k, 0)\n",
"\n",
"print(f\"\\n\ud83c\udfc1 Done: {total['laps']:,} laps | {total['pits']} pit stops | \"\n",
" f\"{total['events']} race events embedded as VECTOR(384, FLOAT32)\")\n"
]
},
{
"cell_type": "markdown",
"id": "md_13",
"metadata": {},
"source": [
"---\n",
"## Paradigm 1: Relational SQL \u2014 Tyre Strategy at Miami (2022\u20132025)\n",
"\n",
"**Oracle features:** CTEs, `ROW_NUMBER() OVER`, `PARTITION BY`, aggregation\n",
"\n",
"Standard SQL \u2014 but demonstrating that Oracle 26ai doesn't sacrifice relational\n",
"capability to gain vector and graph features. One engine, all paradigms.\n",
"\n",
"The `query_winner_strategy` function uses a CTE to identify the race winner\n",
"(driver in P1 on the final lap) then reconstructs their full stint sequence.\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "code_14",
"metadata": {
"execution": {
"iopub.execute_input": "2026-04-15T10:43:20.122766Z",
"iopub.status.busy": "2026-04-15T10:43:20.122570Z",
"iopub.status.idle": "2026-04-15T10:43:20.184359Z",
"shell.execute_reply": "2026-04-15T10:43:20.183854Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\ud83c\udfce\ufe0f Miami GP \u2014 Winner Strategies (2022\u20132025)\n",
"=======================================================\n",
"\n",
"2022: VER (Red Bull Racing) \u2014 MEDIUM \u2192 HARD\n",
" MEDIUM laps 2\u201326 (25 laps, avg 94.156s)\n",
" HARD laps 27\u201357 (27 laps, avg 95.525s)\n",
"\n",
"2023: VER (Red Bull Racing) \u2014 HARD \u2192 MEDIUM\n",
" HARD laps 2\u201345 (44 laps, avg 92.144s)\n",
" MEDIUM laps 46\u201357 (12 laps, avg 91.847s)\n",
"\n",
"2024: NOR (McLaren) \u2014 MEDIUM \u2192 HARD\n",
" MEDIUM laps 2\u201329 (28 laps, avg 94.954s)\n",
" HARD laps 30\u201357 (27 laps, avg 93.911s)\n",
"\n",
"2025: PIA (McLaren) \u2014 MEDIUM \u2192 HARD\n",
" MEDIUM laps 25\u201332 (8 laps, avg 97.414s)\n",
" HARD laps 33\u201357 (25 laps, avg 91.436s)\n"
]
}
],
"source": [
"import pandas as pd\n",
"import plotly.graph_objects as go\n",
"\n",
"COMPOUND_COLORS = {\n",
" \"SOFT\":\"#E8002D\", \"MEDIUM\":\"#FFD700\", \"HARD\":\"#F0F0F0\",\n",
" \"INTERMEDIATE\":\"#39B54A\", \"WET\":\"#0067FF\", \"UNKNOWN\":\"#888888\",\n",
"}\n",
"\n",
"def query_tire_strategy(conn, season: int, race_name: str) -> pd.DataFrame:\n",
" \"\"\"Stint-by-stint tyre allocation for all classified drivers.\"\"\"\n",
" return pd.read_sql(\"\"\"\n",
" SELECT\n",
" driver, team, compound,\n",
" MIN(lap_number) AS stint_start,\n",
" MAX(lap_number) AS stint_end,\n",
" COUNT(*) AS stint_laps,\n",
" ROUND(AVG(lap_time_s), 3) AS avg_lap_s,\n",
" MIN(position) AS best_pos\n",
" FROM race_laps\n",
" WHERE season = :season\n",
" AND race_name = :race\n",
" AND lap_time_s BETWEEN 60 AND 250\n",
" AND compound != 'UNKNOWN'\n",
" GROUP BY driver, team, compound\n",
" ORDER BY best_pos NULLS LAST, stint_start\n",
" \"\"\", conn, params={\"season\": season, \"race\": race_name})\n",
"\n",
"def query_winner_strategy(conn, season: int, race_name: str) -> pd.DataFrame:\n",
" \"\"\"Race winner's full stint breakdown using a CTE to isolate P1 finisher.\"\"\"\n",
" return pd.read_sql(\"\"\"\n",
" WITH winner AS (\n",
" SELECT driver FROM (\n",
" SELECT driver, position,\n",
" ROW_NUMBER() OVER (ORDER BY lap_number DESC) rn\n",
" FROM race_laps\n",
" WHERE season=:season AND race_name=:race AND position=1\n",
" ) WHERE rn = 1\n",
" )\n",
" SELECT rl.driver, rl.team, rl.compound,\n",
" MIN(rl.lap_number) AS stint_start,\n",
" MAX(rl.lap_number) AS stint_end,\n",
" COUNT(*) AS stint_laps,\n",
" ROUND(AVG(rl.lap_time_s),3) AS avg_lap_s\n",
" FROM race_laps rl JOIN winner w ON rl.driver=w.driver\n",
" WHERE rl.season=:season AND rl.race_name=:race\n",
" AND rl.lap_time_s BETWEEN 60 AND 250\n",
" AND rl.compound != 'UNKNOWN'\n",
" GROUP BY rl.driver, rl.team, rl.compound\n",
" ORDER BY stint_start\n",
" \"\"\", conn, params={\"season\": season, \"race\": race_name})\n",
"\n",
"# Show winner strategies across all 4 Miami GPs\n",
"print(\"\ud83c\udfce\ufe0f Miami GP \u2014 Winner Strategies (2022\u20132025)\")\n",
"print(\"=\" * 55)\n",
"for yr in [2022, 2023, 2024, 2025]:\n",
" df_w = query_winner_strategy(CONN, yr, \"Miami\")\n",
" if len(df_w) > 0:\n",
" winner = df_w[\"DRIVER\"].iloc[0]\n",
" team = df_w[\"TEAM\"].iloc[0]\n",
" stints = \" \u2192 \".join(df_w[\"COMPOUND\"])\n",
" print(f\"\\n{yr}: {winner} ({team}) \u2014 {stints}\")\n",
" for _, s in df_w.iterrows():\n",
" print(f\" {s['COMPOUND']:8s} laps {int(s['STINT_START'])}\u2013{int(s['STINT_END'])} \"\n",
" f\"({int(s['STINT_LAPS'])} laps, avg {s['AVG_LAP_S']:.3f}s)\")\n",
"\n",
"# Use 2025 for the detailed strategy chart\n",
"df_strategy = query_tire_strategy(CONN, 2025, \"Miami\")\n",
"df_winner = query_winner_strategy(CONN, 2025, \"Miami\")\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "code_15",
"metadata": {
"execution": {
"iopub.execute_input": "2026-04-15T10:43:20.186016Z",
"iopub.status.busy": "2026-04-15T10:43:20.185880Z",
"iopub.status.idle": "2026-04-15T10:43:21.233039Z",
"shell.execute_reply": "2026-04-15T10:43:21.232611Z"
}
},
"outputs": [
{
"data": {
"text/html": [
" \n",
" "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"base": 25,
"hovertemplate": "PIA
Compound: MEDIUM
Laps 25\u201332 (8 laps)
Avg lap: 97.414s
Compound: HARD
Laps 33\u201357 (25 laps)
Avg lap: 91.436s
Compound: MEDIUM
Laps 25\u201332 (8 laps)
Avg lap: 97.262s
Compound: HARD
Laps 33\u201357 (25 laps)
Avg lap: 91.324s
Compound: MEDIUM
Laps 25\u201332 (8 laps)
Avg lap: 98.874s
Compound: HARD
Laps 33\u201357 (25 laps)
Avg lap: 91.934s
Compound: HARD
Laps 25\u201332 (8 laps)
Avg lap: 98.085s
Compound: MEDIUM
Laps 33\u201357 (25 laps)
Avg lap: 91.956s
Compound: MEDIUM
Laps 25\u201332 (8 laps)
Avg lap: 99.113s
Compound: HARD
Laps 33\u201357 (25 laps)
Avg lap: 92.155s
Compound: MEDIUM
Laps 25\u201332 (8 laps)
Avg lap: 98.866s
Compound: HARD
Laps 33\u201357 (25 laps)
Avg lap: 92.082s
Compound: MEDIUM
Laps 25\u201332 (8 laps)
Avg lap: 99.404s
Compound: HARD
Laps 33\u201357 (25 laps)
Avg lap: 92.301s
Compound: HARD
Laps 24\u201332 (9 laps)
Avg lap: 97.617s
Compound: MEDIUM
Laps 33\u201357 (25 laps)
Avg lap: 92.240s
Compound: MEDIUM
Laps 25\u201332 (8 laps)
Avg lap: 99.578s
Compound: HARD
Laps 33\u201357 (25 laps)
Avg lap: 92.380s
Compound: MEDIUM
Laps 25\u201332 (8 laps)
Avg lap: 99.202s
Compound: HARD
Laps 33\u201357 (25 laps)
Avg lap: 92.324s
Oracle AI Database 26ai | Paradigm 1: Relational SQL | Source: FastF1"
},
"xaxis": {
"gridcolor": "#2a2a3e",
"title": {
"text": "Lap Number"
}
}
}
},
"text/html": [
"