Skip to main content
Midwicket

Midwicket

Cricket Data Infrastructure

20,888+ Matches  ·  9,148,005+ Deliveries  ·  25+ Years of Coverage

Open In Colab   PyPI   CI   Python   MIT

Ball-by-ball cricket analytics. Local. Fast. No cloud required.


Why Midwicket?

These are real findings — generated in seconds from the IPL corpus using Midwicket's query engine.

Finding How Midwicket got there
Virat Kohli's 2026 IPL season (155.6 SR) is his fastest ever — at age 37 Season-by-season strike rate over 19 consecutive IPL seasons
Sixes per match nearly doubled — 10.7 (2008) → 19.3 (2026) — while dot ball % fell 5.4 points 1,239 matches, 18-season trend decomposition
Vaibhav Suryavanshi: 211 SR in Powerplay — the highest ever recorded in IPL 272 powerplay balls, 51 sixes, 35.7% dot rate
85% of IPL batters perform better when chasing than when setting a target SR uplift (2nd innings – 1st innings) for 200+ batters
DW Steyn's 44.65% dot rate at 6.79 economy would be structurally impossible in 2024 IPL Era-segmented dot ball analysis across all 141 IPL death bowlers

See all 10 showcase analyses →


Quick Start

30 seconds. No data download. No account.

pip install midwicket
import midwicket.express as px

# Win probability — works instantly, bundled in-memory data
result = px.predict_win(
    venue="Wankhede Stadium",
    target=180,
    current_score=120,
    wickets_down=5,
    overs_done=15.0,
)
print(f"Win probability: {result['win_prob']:.1%}")
# Win probability: 22.5%

That's it. The model runs locally, no API key, no download.

Open in Colab → — zero-install, browser-based.


Loading Datasets

Midwicket connects to Cricsheet and manages download, extraction, and ingestion automatically.

from midwicket.datasets import load_dataset

# IPL — 1,100+ matches, 2008–present (~50 MB, downloads once)
session = load_dataset("ipl")

# Big Bash League
session = load_dataset("bbl")

# Everything — all formats, all genders, 25+ years
session = load_dataset("all")

Available datasets:

Key Competition Est. Matches
"ipl" Indian Premier League 1,100+
"t20s" T20 Internationals (M + W) 3,200+
"bbl" Big Bash League 650+
"psl" Pakistan Super League 350+
"cpl" Caribbean Premier League 380+
"wbbl" Women's Big Bash League 550+
"odis" One Day Internationals 2,400+
"tests" Test Matches 700+
"all_t20" All T20 globally 8,500+
"all" Complete Cricsheet corpus 16,000+

Once loaded, a session gives you a thread-safe DuckDB engine over ball-by-ball events. Query anything:

df = session.engine.execute_sql("""
    SELECT batter,
           SUM(runs_batter) AS runs,
           ROUND(SUM(runs_batter) * 100.0 / COUNT(*), 1) AS strike_rate,
           COUNT(DISTINCT match_id) AS matches
    FROM ball_events
    WHERE over >= 15              -- death overs only
    GROUP BY batter
    HAVING COUNT(*) >= 100
    ORDER BY runs DESC LIMIT 10
""").to_pandas()

Feature Store

Six production-grade metrics, computed from ball-by-ball data:

from midwicket.features import (
    build_pressure_index,
    build_bowler_quality_rating,
    build_match_context_score,
    build_venue_bias_rating,
    build_batter_intent_score,
    build_expected_runs,
)

# Pressure Index — situational leverage per delivery
pi = build_pressure_index(session)
# Returns DataFrame: match_id, inning, over, ball, batter_id, bowler_id, pressure_index

# Bowler Quality Rating — dot balls + wicket rate combined
bqr = build_bowler_quality_rating(session)
# Returns DataFrame: bowler_id, total_balls, dot_balls, wickets, bowler_quality_rating

# Venue Bias Rating — batter-friendly vs bowler-friendly grounds
vbr = build_venue_bias_rating(session)
# VBR > 1.0 = batter-friendly  |  VBR < 1.0 = bowler-friendly
# Venues with < 5 matches default to VBR = 1.0 (stabilised)

# Match Context Score — chase pressure at any moment in the 2nd innings
mcs = build_match_context_score(session)

All features support date filtering — analyse any historical window without leakage:

bqr_2023 = build_bowler_quality_rating(session, start_date="2023-01-01", end_date="2023-12-31")

Scouting Reports

import midwicket as md

session = md.init("./data")          # point at your local dataset
report = md.scouting_report("Virat Kohli")

print(report["role"])                # "Batter"
print(report["strengths"])           # ["Powerplay anchor", "Middle-over accelerator", ...]
print(report["phase_batting"])       # {"Powerplay": {...}, "Middle": {...}, "Death": {...}}
print(report["venue_performance"])   # per-venue batting average and SR
print(report["recent_form"])         # last-N-matches rolling stats

The scouting report resolves name aliases automatically — "V Kohli", "Virat Kohli", "kohli" all resolve to the same entity across 17+ seasons.


Ten analyses built on real IPL data. Click any image to see the full walkthrough.

All-Time Run Leaders

Run Leaders

Kohli's 9,228 runs lead by 1,897. Bars coloured by strike rate — greener hits faster.

IPL Scoring: 18 Years of Evolution

Season Trends

Avg 1st innings: 161 (2008) → 192 (2026). Sixes per match nearly doubled.

Venue Scoring Atlas (76 grounds)

Venue Atlas

VBR 0.848 → 1.253 across IPL grounds. 40% swing in expected scoring.

Death Over Bowler Landscape

Death Bowlers

141 bowlers, economy vs wicket rate. Bumrah: #11, economy 8.07.

Chase Specialists

Chase Scatter

85%+ of batters hit harder when chasing. Pat Cummins: +46 SR points.

Powerplay Kings

Powerplay Kings

Suryavanshi: 211 SR — the highest ever recorded in IPL powerplay.

View all 10 showcases with charts, queries, and walkthroughs →


Five-Minute Tutorial

New to Midwicket? docs/getting_started.md takes you from install to first insight in under 5 minutes — using real data, real outputs.


Examples

The examples/ directory contains 36 runnable scripts organised by complexity:

Scripts Topic
01–05 Session setup, data ingest, player lookup, venue stats
06–15 Win prediction, fantasy points, SQL queries, season filters
16–27 Leaderboards, partnerships, consistency, full pipeline demos
28–36 Express API, config, debug, full library tour
showcase_01–25 Deep-dive analyses with charts and findings
portfolio/ 14 player and team scouting studies

Start here: examples/28_express_quickstart.py


Architecture

Midwicket separates concerns across five layers. Data flows from raw JSON through a typed ingestion pipeline into a DuckDB analytical store, with a query planner routing between live scans and pre-built feature tables.

Cricsheet JSON
      │
      ▼
┌─────────────────────┐
│  Canonicaliser      │  Strict V1 Arrow schema · retirement fix · int32 upcasting
│  (core/canonicalize)│  Deterministic match_id · venue alias resolution
└──────────┬──────────┘
           │ PyArrow Table
           ▼
┌─────────────────────┐
│  Identity Registry  │  Player / venue / team aliases across 25+ years
│  (storage/registry) │  Temporal-safe: resolves names at match date, not today
└──────────┬──────────┘
           │
           ▼
┌─────────────────────┐
│  DuckDB Engine      │  Thread-safe · snapshot management · temporal filtering
│  (storage/engine)   │  ball_events: 9M+ rows · sub-second aggregations
└──────────┬──────────┘
           │
      ┌────┴────┐
      ▼         ▼
 Feature     Express
  Store        API
(features.py) (express.py)
      │         │
      └────┬────┘
           ▼
   FastAPI + Prometheus
   (midwicket/serve/)

Data integrity guarantees:

  • Schema version-locked (BALL_EVENT_SCHEMA v1.0.0) — breaking changes are explicit
  • over stored as int16, runs as int32 — no silent overflow on aggregation
  • Retirements classified correctly: RETIRED_HURT/RETIRED_NOT_OUT → is_wicket=False
  • Temporal filters are leak-proof — verified against 4 cutoff dates, 0 leaked rows

Enterprise Deployment

git clone https://github.com/CodersAcademy006/Midwicket.git && cd Midwicket
cp .env.example .env           # set MIDWICKET_SECRET_KEY, MIDWICKET_API_KEYS
docker-compose up -d           # FastAPI + Prometheus + Grafana

The FastAPI service exposes REST endpoints for win probability, player stats, matchups, and scouting reports. Prometheus scrape config and a Grafana dashboard definition are included.


Contributing

Contributions welcome. Areas where help is most needed:

  • Additional competition datasets (WBBL scouting, CPL analysis)
  • Jupyter notebook tutorials for the showcase analyses
  • Performance benchmarks across dataset sizes
  • Documentation translations

Read CONTRIBUTING.md before submitting a PR.


MIT License · Built on Cricsheet data · Powered by DuckDB + PyArrow

Getting Started · Showcase Gallery · API Reference · Changelog

Metadata

Release files for midwicket 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for midwicket 1.1.0
File Size Uploaded
midwicket-1.1.0.tar.gz 5.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for midwicket 1.1.0
File Interpreter ABI Platform
midwicket-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 10.3 MB

Release files / midwicket-1.1.0.tar.gz

Download URL midwicket-1.1.0.tar.gz
Size 5.2 MB
Tags Source
SHA-256 checksum
How to use checksums
68e9459ffe85b3e41e6d2f50b5541ea0018fe2099ef9c7f2a0c85d8c38d6e01f
BLAKE2b-256 checksum
How to use checksums
9424859462dacd770b851b919f1770c1370141899026ea8e3cf01ded35dd56c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 31, 2026.

Transparency log

Release files / midwicket-1.1.0-py3-none-any.whl

Download URL midwicket-1.1.0-py3-none-any.whl
Size 5.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
5e29cef35ef8719a197fdb72e48ca9dfc9b13ee35cc5c13953c18062babf9522
BLAKE2b-256 checksum
How to use checksums
4f9ff40fc9f9e0dea380f5436648b48c86c03475a386092dfb06e33a33914943
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 31, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page