An interactive Formula 1 data explorer with live telemetry, strategy analysis, and race storytelling β built entirely on free, open data sources.
Run it in 2 commands:
git clone https://github.com/AkshayTharval/f1-race-intelligence.git cd f1-race-intelligence && docker-compose upThen open http://localhost:8501
Each driver gets their official team colour. Click any driver name in the legend to isolate them (grey out all others). Use the multiselect above the chart to pin multiple drivers for comparison.
| View | What it shows |
|---|---|
| Race Story | Lap-by-lap position chart for all 20 drivers with safety car / VSC / red flag period annotations. Click legend to isolate drivers. |
| Strategy Board | Tyre stint Gantt chart with official compound colours + undercut/overcut detector per pit stop |
| Driver Telemetry | Smoothed fastest-lap overlay β speed, throttle, brake, gear comparison for any two drivers |
| Season Standings | Championship points progression, constructor standings, teammate head-to-head by round |
| Live Race | Real-time timing (auto-refreshes every 30s during live sessions; shows most recent race otherwise) |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β docker-compose β
β β
β βββββββββββββββββββββββ ββββββββββββββββββββββββββββ β
β β FastAPI Backend β β Streamlit Dashboard β β
β β :8000 ββββββ :8501 β β
β β β β β β
β β /races/{year} β β Race Story β β
β β /race/.../story β β Strategy Board β β
β β /race/.../strategy β β Driver Telemetry β β
β β /race/.../telemetryβ β Season Standings β β
β β /season/.../stand. β β Live Race β β
β β /live/session β β β β
β ββββββββββββ¬βββββββββββ ββββββββββββββββββββββββββββ β
β β β
β ββββββββββββΌβββββββββββββββββββββββββββββββ β
β β Data Layer β β
β β FastF1 (disk cache ./f1_cache/) β β
β β OpenF1 API (live + historical) β β
β β Jolpica API (historical back to 1950) β β
β β SQLite TTL cache (./data/cache/) β β
β βββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Source | What it provides | Auth |
|---|---|---|
| FastF1 | Lap data, telemetry, tyre compounds, session data, race control messages | None |
| OpenF1 API | Live timing, pit stops, stints, driver info | None |
| Jolpica / Ergast | Historical race results & standings back to 1950 | None |
Cost: $0 β All data sources are completely free.
# 1. Clone and install
git clone https://github.com/AkshayTharval/f1-race-intelligence.git
cd f1-race-intelligence
pip install -r requirements.txt
# 2. Start the API backend (terminal 1)
uvicorn backend.main:app --host 0.0.0.0 --port 8000
# β API + Swagger docs at http://localhost:8000/docs
# 3. Start the dashboard (terminal 2)
streamlit run dashboard/app.py
# β Dashboard at http://localhost:8501Python version: Tested on Python 3.9 (Anaconda) and 3.12 (Homebrew). Uses
Optional[T]type hints for 3.9 compatibility.
Auto-generated Swagger UI at http://localhost:8000/docs
| Endpoint | Description |
|---|---|
GET /races/{year} |
List all races in a season with circuit info |
GET /race/{year}/{round}/story |
Lap-by-lap positions for all 20 drivers + race events (SC, VSC, red flags) |
GET /race/{year}/{round}/strategy |
Tyre stints, pit stops, undercut/overcut analysis |
GET /race/{year}/{round}/telemetry/{driver} |
Smoothed fastest-lap telemetry (speed, throttle, brake, gear) |
GET /season/{year}/standings |
Championship points progression round by round |
GET /live/session |
Current or most recent session with live timing |
All responses include X-Cache: HIT/MISS header. Cached in SQLite:
- 5 minutes β live session data
- 24 hours β historical race data (races, telemetry, standings)
- Backend: Python, FastAPI, uvicorn, aiosqlite
- Data: FastF1 3.7+, httpx (OpenF1 + Jolpica APIs)
- Frontend: Streamlit 1.35+, Plotly
- Infrastructure: Docker, Docker Compose, SQLite
| Compound | Colour |
|---|---|
| Soft | π΄ #FF3333 |
| Medium | π‘ #FFF200 |
| Hard | βͺ #FFFFFF |
| Intermediate | π’ #39B54A |
| Wet | π΅ #0067FF |
Team colours are hardcoded from official F1 branding (see TEAM_COLOURS in backend/f1_data.py). Teammates receive a brightened shade of their team colour to remain visually distinct on the position chart.
- First load of a race session takes 30β60 seconds while FastF1 downloads timing data from the F1 timing server. All subsequent loads are instant (disk-cached in
./f1_cache/). - The
./f1_cache/directory can grow to several GB for a full season of data. - Race events (safety car, VSC) are read directly from FastF1's
race_control_messagesDataFrame which includes an exactLapcolumn β no time-based mapping needed. - Jolpica API requires
.jsonsuffix on all endpoint URLs (e.g./2024.json).
The test suite uses pytest and pytest-asyncio. No network calls or FastF1 downloads are needed β all external dependencies are mocked.
pip install -r requirements-dev.txtThe main
requirements.txtmust also be installed (see Quick Start above).
pytestpytest tests/test_cache.py # TTL cache logic
pytest tests/test_f1_data.py # Data processing & API parsing
pytest tests/test_strategy.py # Undercut/overcut detector algorithm
pytest tests/test_routers.py # HTTP endpoints (cache headers, 404s, etc.)pytest -vpip install pytest-cov
pytest --cov=backend --cov-report=term-missing| Module | Tests cover |
|---|---|
backend/cache.py |
TTL constants, get/set round-trip, expiry, upsert, concurrent writes, idempotent init_db |
backend/f1_data.py |
Tyre colours, lap position extraction (NaN fill, retirement), tyre stints, race event parsing (VSC/SC/Red Flag/skips), driver colour logic (team lookup, teammate brightening, fallback palette), OpenF1/Jolpica data parsing |
backend/routers/strategy.py |
Undercut Success, Overcut Success, Undercut Failed, Neutral (no competitors, no lap data, unchanged position), edge cases |
backend/routers/*.py |
Health check, cache HIT/MISS headers, 404 on missing session, driver abbreviation uppercasing, position sorting, colour # prefix normalisation |
PRs welcome. Follow the visualisation rules in CLAUDE.md.
MIT

