Skip to main content

Tour de France race outcome prediction: rider archetypes, a top-10 model, and Tissot fantasy team picks by exact knapsack.

Project description

wraith-tdf-predictor 🚴💨

Who cracks the top 10 in July? Six seasons of ProCyclingStats results, a from-scratch model, and a Tissot fantasy team picked by exact knapsack — all in pure Python. No torch, no sklearn, no 200 MB wheel for a model with nine weights.

The 2026 hot take so far: Pogačar. Groundbreaking stuff.

What it does

  • Scrapes grand tours, one-week stage races, monuments and top classics (men's elite, 2021–2026) into SQLite
  • Clusters riders into archetypes with hand-rolled k-means
  • Predicts top-10 finishes with class-weighted logistic regression (test AUC ~0.89 — form really is everything in cycling)
  • Picks a 10-rider, 120-star Tissot fantasy team via 0/1 knapsack with cardinality, backtested leave-one-year-out against the hindsight-optimal team
  • Publishes a static predictions page (data.json) with per-stage teams, jersey picks, and pred-vs-actual grading during the Tour

Install

pip install wraith-tdf-predictor    # or: uv add wraith-tdf-predictor

Runtime dependencies: procyclingstats and cloudscraper. That's it. Python 3.12+.

Run it

From a clone:

git clone https://git.thomaspeoples.com/thomaspeoples/wraith-tdf-predictor.git
cd wraith-tdf-predictor
uv run poe setup      # deps, hooks, .env from template — once

uv run poe ingest     # scrape PCS -> data/raw/*.json (polite, cached)
uv run poe db         # load -> data/races.db (SQLite)
uv run poe model      # archetypes + top-10 model
uv run poe fantasy    # backtest + 2026 team pick
uv run poe publish    # data.json for the static predictions page
docker compose up -d  # browse the DB at :8080

uv run poe update     # daily during the Tour: ingest new stage if
                       # raced, retrain, republish -- no-op otherwise

Outputs land in data/: archetypes.json, model.json, and a printed team that will absolutely not win your league.

Configuration

Everything configurable lives in .env (copied from .env.example by poe setup, never committed):

Variable Default Purpose
DATA_DIR ./data Scraped data, SQLite DB, model outputs
WWW_DIR $DATA_DIR/www Where poe publish writes data.json
TISSOT_USER / TISSOT_PASS Only for scraping the Tissot game yourself

Poe tasks load .env automatically; direct python -m runs want uv run --env-file .env ....

Where the data comes from (and how politely it's scraped): docs/SOURCES.md.

Hacking on it

uv run poe test         # pytest, coverage >80% enforced
uv run poe tidy         # ruff lint + format
uv run poe docs-serve   # MkDocs on :8000
uv run cz commit        # commits go through commitizen, no exceptions

Full workflow in CONTRIBUTING.md.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wraith_tdf_predictor-0.9.0.tar.gz (161.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wraith_tdf_predictor-0.9.0-py3-none-any.whl (31.7 kB view details)

Uploaded Python 3

File details

Details for the file wraith_tdf_predictor-0.9.0.tar.gz.

File metadata

  • Download URL: wraith_tdf_predictor-0.9.0.tar.gz
  • Upload date:
  • Size: 161.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for wraith_tdf_predictor-0.9.0.tar.gz
Algorithm Hash digest
SHA256 60ec423cc38a222822e3b6d5b877f8ebe11894a750a3cc78727cb2021528dd1f
MD5 29512cf577d6048868fec26e9548f5f9
BLAKE2b-256 361fb01ebaacaab75f7f1a0090ee95a3e45c7bd01c312c040abfd2f56d86d671

See more details on using hashes here.

File details

Details for the file wraith_tdf_predictor-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: wraith_tdf_predictor-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 31.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for wraith_tdf_predictor-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2366a3a285d7c74929297c2c0eac8033e25d8ca902a05503be3bc518e5989725
MD5 92dbb2c12a8c545c8f0cc0a8f6476e57
BLAKE2b-256 d2f64b3bdc5c31e18a58605f902df6c302516141c3b6402dbe7fc45c407042b1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page