Self-hosted, runs locally with your own Kaggle session

Study your Kaggle replays at scale.

Kaggle simulation competitions produce thousands of match replays, but the website only lets you reach them one click at a time. Kaggle Replays gives you one screen to browse competitions, submissions, and episodes, filter by outcome, and bulk-download replays — without hammering Kaggle's API or risking your account.

The problem

Replay analysis should be easy and safe.

Studying replays is one of the best ways to improve a competition agent, but doing it by hand is slow, and automating it naively is dangerous: Kaggle's internal API rate-limits aggressively, and a tight request loop can get your account throttled or banned. This project is built around avoiding exactly that.

Convenient

Browse competitions, submissions, and per-submission episodes; see real skill-rating scores; filter episodes by win, loss, or draw; and bulk-download replays as JSON or ZIP with live progress.

Safe by design

Every read in the interface is served from a local database cache. The live Kaggle API is touched only by a once-a-day scheduler or an explicit "Sync now" — never automatically on page loads or navigation.

What it does

Everything around your episodes, in one place.

01

Competitions

Lists the competitions you have entered, with active or completed status.

02

Submissions

Real skill-rating scores and episode counts per submission, served from cache.

03

Episodes

Each episode classified as win, loss, or draw from the agents' terminal rewards.

04

Bulk download

Download replays as JSON or ZIP, optionally filtered by outcome, with live WebSocket progress.

05

Leaderboard

Current public standings with the top-ten-percent cutoff, a competition selector, and search.

06

Top 10% Replays

Dated leaderboard snapshots and the replay episode IDs of the top performers over time.

How it works

An authenticated browser session, then a local cache.

Kaggle has no public API for simulation episodes, so the backend drives an already-authenticated Playwright browser session (saved once via an interactive login) to call the same internal endpoints the website uses. The results are written to MySQL, and the interface reads from there.

Kaggle internal API --(Playwright session)--> Backend services | writes to v MySQL cache | reads from v Browser (React SPA) <-------(REST + WebSocket)------ FastAPI routers

Drill-down

competitions → submissions → episodes → replays. Each level is fetched once, cached, then served locally.

Real scores

A submission's score is the agent skill rating from the latest episode, not the empty "formatted" field — so it never shows a misleading 0.

Rate-limit-safe

Live calls happen only on a daily schedule or an explicit sync, paced sequentially, stopping on the first rate-limit response.

Architecture

Three layers, one cache between them.

ComponentResponsibility
downloader.pyAsync Playwright client for Kaggle's internal API: list competitions / submissions / episodes, fetch replays in batches, classify outcomes.
backend/ (FastAPI)REST + WebSocket API, MySQL persistence, JWT auth, security layer, per-user Playwright context pool, and a daily sync scheduler.
MySQLThe cache the UI reads from: competitions, submissions, episode lists, scores, and dated leaderboard snapshots.
Frontend (React + TS)Vite single-page app with an in-memory access token, light/dark themes, and live download progress.
Get started

Run it locally in a few steps.

Full instructions are in the repository README. In short:

# 1. Database
brew services start mysql   # create the kaggle_replays DB + a user

# 2. Backend
cd Backend
python3 -m venv .venv
.venv/bin/python -m pip install -r backend/requirements.txt
.venv/bin/python -m playwright install chromium
cp backend/.env.example backend/.env   # fill in DB URL + JWT secrets
.venv/bin/python login.py              # log in to Kaggle once -> auth.json
.venv/bin/python -m alembic -c backend/alembic.ini upgrade head
.venv/bin/python -m uvicorn backend.main:app --port 8000

# 3. Frontend (another terminal)
cd Frontend
npm install
npm run dev                            # http://localhost:5173

Why this is a local tool. The backend authenticates to Kaggle as you, using your saved browser session (auth.json). Hosting the live application on a public server would place your personal Kaggle credentials there and could violate Kaggle's Terms of Service, so the application is meant to run locally for your own account. This page is the project's public face; the app itself stays on your machine.