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 — sequential multi-month game retrieval across date ranges
- 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 exceptions —
PlayerNotFoundError,RateLimitError,DataGoneErrorso 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 (multi-month)
from datetime import date
from chesscompy import get_games_batch, get_games_batch_by_opening
# Fetch Oct 2025 through Jan 2026 sequentially (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 wrappingexceptions.py—ChessComAPIError,PlayerNotFoundError,DataGoneError,RateLimitErrorgames.py—get_games,get_games_by_opening,get_games_batch,get_games_batch_by_opening,get_recent_losses,filter_by_time_controlpgn.py—extract_clocks,extract_clocks_by_color,extract_moves,find_time_pressure_movesstats.py—get_player_stats
cli.py— command-line tool for manual testingtests/— unit tests for all modulespyproject.toml— metadata, dependencies, tool configresponses/— sample API responses (for tests)
License
MIT (see LICENSE).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chesscompy-0.3.0.tar.gz.
File metadata
- Download URL: chesscompy-0.3.0.tar.gz
- Upload date:
- Size: 29.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91d55ef447911add0cb7a267f9a72b4585759f2666faf144cbc41a58d00112ca
|
|
| MD5 |
1b118f0c0d928b7e5de60798dd13306f
|
|
| BLAKE2b-256 |
b3a647b3a3c72e9f5f2c2219d0593d7787eab68c8be87934bdb67e2e8d8fb466
|
File details
Details for the file chesscompy-0.3.0-py3-none-any.whl.
File metadata
- Download URL: chesscompy-0.3.0-py3-none-any.whl
- Upload date:
- Size: 17.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f96eb546be2d95007c7cd31ae66d4fd015b8579495ebb64b09fca7a327956f84
|
|
| MD5 |
51eeb02852ce3d7a4106a43cb5db2b5e
|
|
| BLAKE2b-256 |
1a0acec01d9584f6438d31826fcf558d744ba9f148daf69c67e38743feada715
|