Skip to main content

Python library extending the Chess.com public API — batch game fetching, opening filters, PGN parsing, stats, and more

Project description

chesscompy

A Python library that extends the Chess.com public API. Fetch games by opening, batch-fetch across date ranges with concurrency, parse PGN clock/move data, pull player stats, and detect time-pressure blunders — all from a simple Python interface.

Features

  • Games by opening — filter by ECO code ("B07") or opening name substring ("Caro-Kann")
  • Batch fetching — concurrent multi-month game retrieval via thread pool
  • Time control filters — narrow results to bullet, blitz, rapid, or daily
  • Recent losses — walk backwards through months to find your latest losses
  • Player stats — current ratings and W/L/D records across all formats
  • PGN parsing — extract clock times, move lists, and time-pressure moves from Chess.com PGNs
  • Custom exceptionsPlayerNotFoundError, RateLimitError, DataGoneError so you never need to inspect raw HTTP status codes
  • Automatic retries — exponential backoff on 429 (rate limit) responses

Install

pip install chesscompy

Development

For an editable install with test tools:

git clone https://github.com/cdewitt02/chesscompy.git
cd chesscompy
python3 -m venv .venv
source .venv/bin/activate   # Linux/macOS (.venv\Scripts\activate on Windows)
pip install -e ".[dev]"

Run tests:

pytest tests/ -v

Usage

Fetch games

from chesscompy import get_games, get_games_by_opening

# All games for a player in a single month
games = get_games("cdew4", 2026, 1)

# Filter that month by opening (ECO code or name substring)
pirc_games = get_games_by_opening("cdew4", "B07", 2026, 1)
caro_games = get_games_by_opening("cdew4", "Caro-Kann", 2026, 1)

# All games in a year matching an opening (12 API calls, then filter)
caro_in_year = get_games_by_opening("cdew4", "Caro-Kann", 2026)

Each game is a dict with the same shape as the Chess.com API: url, pgn, white, black, eco, time_control, fen, etc.

Batch fetch (concurrent)

from datetime import date
from chesscompy import get_games_batch, get_games_batch_by_opening

# Fetch Oct 2025 through Jan 2026 concurrently (one request per month)
all_games = get_games_batch("cdew4", date(2025, 10, 1), date(2026, 1, 31))

# With filters: only blitz games since a Unix timestamp
blitz = get_games_batch(
    "cdew4", date(2025, 10, 1), date(2026, 1, 31),
    time_control="blitz", since=1704067200,
)

# Batch + opening filter combined
pirc_batch = get_games_batch_by_opening(
    "cdew4", "B07", date(2025, 10, 1), date(2026, 1, 31),
)

Filter by time control

from chesscompy import filter_by_time_control

rapid_only = filter_by_time_control(all_games, "rapid")

Recent losses

from chesscompy import get_recent_losses

# Most recent 5 rapid losses (walks backwards month by month)
losses = get_recent_losses("cdew4", limit=5, time_control="rapid")

Player stats

from chesscompy import get_player_stats

stats = get_player_stats("cdew4")
print(stats["chess_blitz"]["last"]["rating"])   # current blitz rating
print(stats["chess_blitz"]["record"])            # {"win": ..., "loss": ..., "draw": ...}

PGN parsing

from chesscompy import extract_clocks, extract_clocks_by_color, extract_moves
from chesscompy import find_time_pressure_moves

pgn = games[0]["pgn"]

# Clock times (seconds remaining) in move order
clocks = extract_clocks(pgn)

# Separated by color
by_color = extract_clocks_by_color(pgn)
print(by_color["white"])  # White's clock after each move
print(by_color["black"])  # Black's clock after each move

# SAN move list: ["e4", "d6", "d4", "Nf6", ...]
moves = extract_moves(pgn)

# Moves made under time pressure (< 15 seconds on the clock)
pressure = find_time_pressure_moves(pgn, threshold_seconds=15.0)
for p in pressure:
    print(f"Move {p['move_number']} ({p['color']}): {p['move']}  "
          f"— {p['clock_seconds']:.1f}s left")

Error handling

from chesscompy import get_games
from chesscompy import PlayerNotFoundError, RateLimitError, DataGoneError

try:
    games = get_games("nonexistent_user_xyz", 2026, 1)
except PlayerNotFoundError as e:
    print(f"No such player: {e.username}")
except RateLimitError:
    print("Rate limited — back off and retry later")
except DataGoneError as e:
    print(f"Data permanently removed: {e.url}")

The HTTP client retries automatically on 429 with exponential backoff (up to 3 retries). RateLimitError is only raised after all retries are exhausted.

CLI

A quick CLI (cli.py) is included for manual testing against the live API:

# Single month
python cli.py cdew4 2026-01

# Multi-month range
python cli.py cdew4 2025-10 2026-01

# Filter by opening
python cli.py cdew4 2025-10 2026-01 --opening B07

# Filter by time control
python cli.py cdew4 2025-10 2026-01 --time-control blitz

# Only losses
python cli.py cdew4 2025-10 2026-01 --losses-only

# Combine filters with verbose output
python cli.py cdew4 2025-10 2026-01 --time-control rapid --losses-only -v

Project layout

  • chesscompy/ — main package
    • __init__.py — re-exports public API
    • _client.py — HTTP GET with retries, backoff, and custom exception wrapping
    • exceptions.pyChessComAPIError, PlayerNotFoundError, DataGoneError, RateLimitError
    • games.pyget_games, get_games_by_opening, get_games_batch, get_games_batch_by_opening, get_recent_losses, filter_by_time_control
    • pgn.pyextract_clocks, extract_clocks_by_color, extract_moves, find_time_pressure_moves
    • stats.pyget_player_stats
  • cli.py — command-line tool for manual testing
  • tests/ — unit tests for all modules
  • pyproject.toml — metadata, dependencies, tool config
  • responses/ — sample API responses (for tests)

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

chesscompy-0.2.0.tar.gz (29.9 kB view details)

Uploaded Source

Built Distribution

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

chesscompy-0.2.0-py3-none-any.whl (17.7 kB view details)

Uploaded Python 3

File details

Details for the file chesscompy-0.2.0.tar.gz.

File metadata

  • Download URL: chesscompy-0.2.0.tar.gz
  • Upload date:
  • Size: 29.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.13

File hashes

Hashes for chesscompy-0.2.0.tar.gz
Algorithm Hash digest
SHA256 478dbfd49542fdd0395c6e2923d5eceb6f15d6aa0f3107fd02bf7c5b8c94bc76
MD5 5eca30ce2fe1ec25fa7ae057720fce1f
BLAKE2b-256 3b54c40c3553948bf4111566ab09ce57b374240553e5fea840b95601b4243081

See more details on using hashes here.

File details

Details for the file chesscompy-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: chesscompy-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 17.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.13

File hashes

Hashes for chesscompy-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c122036a70d74e6f801fc60930090f00a93f85da0f36aa523d2096ce547ad883
MD5 0d3b07dc4d9bfacfc609375b0343f016
BLAKE2b-256 7d2fd35bd87ac34b91da07d55e079e14a0015e1ea0b23ff4fe6cf25fec421dbf

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