glicko2
A pure Python implementation of the Glicko-2 rating system (Glickman, 2012).
Zero dependencies. Fully typed. Usable as a standalone library or as the rating backend for glicko_eval.
Installation
pip install glicko2-py
# with PostgreSQL support:
pip install "glicko2-py[postgres]"
Quick start
from glicko2 import RatingEngine, MatchResult, RatingPeriod
engine = RatingEngine(tau=0.5)
# Players are auto-created on first use, or register explicitly:
engine.pool.get_or_create("alice")
engine.pool.get_or_create("bob")
period = RatingPeriod(id="round-1")
period.add_match(MatchResult("alice", "bob", 1.0)) # one entry per game
engine.process_period(period) # engine derives bob's perspective automatically
from glicko2.math.conversions import mu_to_rating, phi_to_rd
alice = engine.pool.get("alice")
print(mu_to_rating(alice.mu)) # display rating (~1537)
print(phi_to_rd(alice.phi)) # rating deviation (~192)
Core concepts
| Concept | Description |
|---|---|
Player |
Holds μ, φ, σ in Glicko-2 internal scale |
MatchResult |
One game outcome: score is any float in [0, 1] from player_id's view; engine derives opponent's perspective automatically |
RatingPeriod |
A batch of matches processed together (all treated as simultaneous) |
RatingEngine |
Runs period updates; owns a PlayerPool |
Math
All rating math lives in glicko2.math and is composed of pure functions with no side effects.
from glicko2.math import g, E, update_rating
from glicko2.math import rating_to_mu, rd_to_phi, mu_to_rating, phi_to_rd
from glicko2.math import rating_interval, win_probability
The update_rating() function implements the full Glickman algorithm including the Illinois (regula falsi) root-finding method for the iterative volatility update (Step 5).
Reference values (Glickman 2012, Table 1)
| Before | After | |
|---|---|---|
| Rating | 1500 | 1464.06 |
| RD | 200 | 151.52 |
| Volatility σ | 0.06 | 0.059996 |
Tournament formats
from glicko2.tournament import round_robin, swiss, adaptive
from glicko2.tournament import all_below_rd_threshold, top_k_separated
| Format | Description |
|---|---|
round_robin |
Every player faces every other player once |
double_round_robin |
Every ordered pair plays |
swiss |
μ-sorted pairing each round |
adaptive |
Select pairings closest to 50/50 win probability |
Storage backends
| Backend | Status | Use case |
|---|---|---|
InMemoryStorage |
Stable | Tests, ephemeral runs |
SQLiteStorage |
Stable | Default persistent backend, zero infra |
PostgresStorage |
Not yet implemented | Planned for shared team leaderboards |
from glicko2.storage import SQLiteStorage
storage = SQLiteStorage("ratings.db")
storage.save_player(engine.pool.get("alice"))
alice = storage.load_player("alice")
Note:
PostgresStorageconnects and migrates the schema but all CRUD methods raiseNotImplementedError. Do not use it in production yet.
Rating inflation utilities
from glicko2.engine import detect_inflation, normalize_ratings, soft_reset
# Detect mean drift
drift = detect_inflation(engine.pool)
# Shift all ratings so the mean returns to 0
normalize_ratings(engine.pool)
# Move ratings halfway back toward defaults (e.g. between seasons)
soft_reset(engine.pool, compression=0.5)
Parameter guidance
| Parameter | Default | Notes |
|---|---|---|
tau (τ) |
0.5 |
System constant. Range 0.3–1.2. Lower = more stable volatility. |
| Initial RD | 350 |
φ = 350/173.7178 ≈ 2.015. Reduce for established players. |
| Initial σ | 0.06 |
Glickman's recommended default. |
Running tests
From the monorepo root:
uv run pytest packages/glicko2/tests/
Metadata
Release files for glicko2-py 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| glicko2_py-0.1.0.tar.gz | 25.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| glicko2_py-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.9 kB
Release files / glicko2_py-0.1.0.tar.gz
| Download URL | glicko2_py-0.1.0.tar.gz |
|---|---|
| Size | 25.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
222c60b1ceb75496cb00bb6ff79f4d3848b1c85ad015b0c817f59884b8bd0bbe
|
|
BLAKE2b-256 checksum How to use checksums |
ef56e943f5902145536f7c2d394876b452569cbafeed1dc1dfea0b2451ce6e73
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Apr 1, 2026.
Transparency logRelease files / glicko2_py-0.1.0-py3-none-any.whl
| Download URL | glicko2_py-0.1.0-py3-none-any.whl |
|---|---|
| Size | 24.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
79a67e2a55af1bc0f97d3184f027c8b40b91425d39a2f3223c2a17dd60c66e8d
|
|
BLAKE2b-256 checksum How to use checksums |
5bf24ff3cde357a72855916eccd3c3a53610e4ee03f31f156e45f8dd20494bd9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Apr 1, 2026.
Transparency log