Logo
Chess Analyzer Pro
ReleasesDocsBlogDownload

Documentation

Getting StartedUsage GuideConfigurationArchitectureFiles & DataHow We Calculate AnalysisChangelogFor DevelopersTroubleshootingAPI ReferenceUI Components

Chess Analyzer Pro

Free offline chess analysis software powered by Stockfish.

Project

  • GitHub Repository
  • Download
  • Documentation
  • Open Source Credits
  • Report Feedback/Bug

Content

  • Blog
  • Documentation
  • Features

Resources

  • Stockfish Engine
  • Beekeeper Studio
  • My Lichess Profile
  • My Chess.com Profile

Developer

  • Portfolio
  • GitHub Profile
  • LinkedIn
  • Contact Me
Released under the MIT License. Open Source Project.
Back to Docs

API Reference

Technical reference for the backend services and APIs in Chess Analyzer Pro.


Overview

The backend layer (src/backend/) provides services for:

  • Game Analysis: Stockfish engine integration and move classification
  • API Integrations: Chess.com, Lichess, and Groq
  • Data Persistence: SQLite-based caching and game history
  • Game Parsing: PGN file and text parsing

Data Models (models.py)

MoveAnalysis

Represents a single move with its analysis data.

@dataclass
class MoveAnalysis:
    move_number: int          # Move number (1, 2, 3...)
    ply: int                  # Ply count (half-moves from start)
    san: str                  # Standard Algebraic Notation (e.g., "Nf3")
    uci: str                  # UCI notation (e.g., "g1f3")
    fen_before: str           # Position before the move
    
    # Engine evaluation (before the move)
    eval_before_cp: Optional[int] = None   # Centipawns
    eval_before_mate: Optional[int] = None # Mate in X
    
    # Best move from engine
    best_move: Optional[str] = None        # UCI notation
    best_eval_cp: Optional[int] = None
    best_eval_mate: Optional[int] = None
    pv: List[str] = []                     # Principal variation
    
    # Evaluation after the move
    eval_after_cp: Optional[int] = None
    eval_after_mate: Optional[int] = None
    
    # Win probabilities (0.0 to 1.0)
    win_chance_before: float = 0.5
    win_chance_after: float = 0.5
    
    # Classification
    classification: str = "Book"  # Brilliant, Best, Excellent, Good, Inaccuracy, Mistake, Blunder, Miss, Book
    explanation: str = ""
    
    # Multi-PV data
    multi_pvs: List[Dict[str, Any]] = []

GameMetadata

Stores game header information.

@dataclass
class GameMetadata:
    white: str = "?"              # White player name
    black: str = "?"              # Black player name
    event: str = "?"              # Event name
    date: str = "?"               # Game date
    result: str = "*"             # Result (1-0, 0-1, 1/2-1/2, *)
    headers: Dict[str, str] = {}  # Raw PGN headers
    
    # Optional metadata
    starting_fen: Optional[str] = None
    white_elo: Optional[str] = None
    black_elo: Optional[str] = None
    time_control: Optional[str] = None
    eco: Optional[str] = None         # ECO opening code
    termination: Optional[str] = None # How game ended
    opening: Optional[str] = None     # Opening name
    source: str = "file"              # file, chesscom, lichess

GameAnalysis

The complete game analysis container.

@dataclass
class GameAnalysis:
    game_id: str                  # Unique identifier
    metadata: GameMetadata        # Game information
    moves: List[MoveAnalysis] = []  # All moves with analysis
    summary: Dict[str, Any] = {}    # Aggregate statistics
    ai_summary: Optional[str] = None  # AI-generated narrative
    pgn_content: Optional[str] = None # Original PGN text

Analyzer (analyzer.py)

The core analysis engine that processes games.

Class: Analyzer

class Analyzer:
    def __init__(self, engine_manager: EngineManager)

Constructor Parameters:

  • engine_manager: An initialized EngineManager instance.

Core Methods

analyze_game(game_analysis, callback=None)

Analyzes a complete game in-place.

def analyze_game(self, game_analysis: GameAnalysis, callback=None)

Parameters:

  • game_analysis: The GameAnalysis object to analyze.
  • callback: Optional function called with (current_move, total_moves) for progress.

Effects:

  • Populates eval_before_cp, eval_after_cp, win_chance_*, classification for each move.
  • Calculates and stores summary with accuracy and classification counts.
  • Saves the game to history database.

get_win_probability(cp, mate)

Converts engine evaluation to win probability.

def get_win_probability(self, cp: Optional[int], mate: Optional[int]) -> float

Parameters:

  • cp: Centipawn evaluation (positive = White advantage).
  • mate: Mate score (positive = White has mate in X).

Returns: Float between 0.0 and 1.0 representing win probability.

Formula:

win_percent = 50 + 50 * (2 / (1 + exp(-0.00368208 * cp)) - 1)

Configuration

analyzer.config = {
    "time_per_move": None,  # Time limit (seconds) or None for depth-based
    "depth": 18,            # Analysis depth
    "multi_pv": 3,          # Number of principal variations
    "use_cache": True       # Use position cache
}

Chess.com API (chess_com_api.py)

Integration with the Chess.com public API.

Class: ChessComAPI

All methods are static.

get_last_games(username, limit=5)

Fetches recent games for a user.

@staticmethod
def get_last_games(username: str, limit: int = 5) -> List[Dict]

Parameters:

  • username: Chess.com username.
  • limit: Maximum number of games to fetch.

Returns: List of dictionaries with game data including pgn, white, black, result.

get_game_by_id(game_id, url=None)

Fetches a specific game by ID.

@staticmethod
def get_game_by_id(game_id: str, url: str = None) -> Optional[Dict]

Parameters:

  • game_id: The game's unique identifier.
  • url: Optional full game URL for fallback parsing.

Returns: Dictionary with pgn key, or None if not found.

extract_game_id(url)

Extracts game ID from a Chess.com URL.

@staticmethod
def extract_game_id(url: str) -> Optional[str]

Supported URL formats:

  • https://www.chess.com/game/live/123456
  • https://www.chess.com/live/game/123456
  • https://www.chess.com/game/daily/123456

Lichess API (lichess_api.py)

Integration with the Lichess API.

Class: LichessAPI

class LichessAPI(BaseChessAPI):
    def __init__(self)

Reads Lichess token from config.json or environment variable.

get_user_games(username, max_games=5)

Fetches recent games for a user.

def get_user_games(self, username: str, max_games: int = 5) -> List[Dict]

Returns: List of normalized game dictionaries compatible with Chess.com format.

get_game_by_id(game_id)

Fetches a specific game by ID.

def get_game_by_id(self, game_id: str) -> dict

Returns: Dictionary with pgn, id, white, black, white_rating, black_rating.

extract_game_id(url)

Extracts game ID from a Lichess URL.

def extract_game_id(self, url: str) -> str

Supported URL formats:

  • https://lichess.org/HuUq2G3x
  • https://lichess.org/HuUq2G3x/white

LLM Service (groq_service.py)

Provider-agnostic LLM service using the OpenAI-compatible API for generating natural language game summaries and coaching insights. Named GroqService for backward compatibility.

Class: GroqService

class GroqService:
    def __init__(self)

Behavior:

  • Automatically resolves the active configuration profile from ConfigManager (including provider, api_key, model_id, and base_url).
  • Natively supports Groq (Cloud), LM Studio (Local), MiniMax (Cloud), and Custom OpenAI-compatible base URLs.
  • Truncates PGN inputs and handles localization using the system language.

configure(api_key)

Configures or reconfigures the service with a new API key.

def configure(self, api_key)

generate_summary(pgn_text, analysis_summary)

Generates a narrative game summary.

def generate_summary(self, pgn_text, analysis_summary) -> str

Parameters:

  • pgn_text: The game's PGN (truncated to 10,000 chars).
  • analysis_summary: Dictionary with accuracy and classification data.

Returns: AI-generated summary with "Game Comment" and narrative.

generate_coach_insights(stats_text)

Generates coaching insights from player statistics.

def generate_coach_insights(self, stats_text) -> str

Parameters:

  • stats_text: Formatted statistics string.

Returns: 3 actionable coaching tips as numbered list.


Game History Manager (game_history.py)

SQLite database manager for persisting analyzed games.

Class: GameHistoryManager

class GameHistoryManager:
    def __init__(self, db_path: str = "analysis_cache.db")

save_game(game_analysis, pgn_content)

Saves a completed analysis to the database.

def save_game(self, game_analysis: GameAnalysis, pgn_content: str)

get_all_games()

Returns all saved games (metadata and summary only).

def get_all_games(self) -> List[Dict]

Sorted by timestamp descending (newest first).

get_games_for_users(usernames)

Returns games where a player matches one of the usernames.

def get_games_for_users(self, usernames: List[str]) -> List[Dict]

Used by the Stats dashboard to filter personal games.

get_game(game_id)

Retrieves a single complete game record.

def get_game(self, game_id: str) -> Optional[Dict]

game_exists(game_id)

Checks if a game with the given ID already exists in the database.

def game_exists(self, game_id: str) -> bool

delete_game(game_id)

Removes a game from history.

def delete_game(self, game_id: str)

clear_history()

Deletes all games from the database.

def clear_history(self)

Analysis Cache (cache.py)

Position-level caching for Stockfish engine analysis evaluations.

Class: AnalysisCache

class AnalysisCache:
    def __init__(self, db_path: Optional[str] = None)

get_analysis(fen, engine_params)

Retrieves cached analysis for a position. Returns result only if the cached evaluation was calculated at an equal or greater search depth.

def get_analysis(self, fen: str, engine_params: dict) -> Optional[List]

Returns: Cached engine output (list of PV data) or None.

save_analysis(fen, engine_params, result)

Saves engine analysis results to the SQLite cache under the analysis table. Overwrites existing records only if the new search depth is higher than the cached depth.

def save_analysis(self, fen: str, engine_params: dict, result: List)

PGN Parser (pgn_parser.py)

Parses PGN files and text into internal data structures.

Class: PGNParser

parse_file(file_path)

Parses a PGN file.

@staticmethod
def parse_file(file_path: str) -> List[GameAnalysis]

Returns: List of GameAnalysis objects (one per game in file).

parse_text(pgn_text)

Parses PGN text directly.

@staticmethod
def parse_text(pgn_text: str) -> List[GameAnalysis]

Book Manager (book.py)

Opening book lookup for position names.

Class: BookManager

get_opening_name(fen, uci_move)

Checks if a position/move is book theory.

def get_opening_name(self, fen: str, uci_move: str) -> Optional[str]

Returns: Opening name if known, otherwise None.


Base API (base_api.py)

Shared utilities for API classes.

Class: BaseChessAPI

class BaseChessAPI:
    DEFAULT_HEADERS = {
        "User-Agent": "ChessAnalyzer/1.0"
    }

_make_request(url, headers=None, params=None)

Makes an HTTP GET request with error handling.

@staticmethod
def _make_request(url, headers=None, params=None) -> Optional[Response]

_safe_json(response)

Safely parses JSON from response.

@staticmethod
def _safe_json(response) -> Optional[dict]

_log_api_error(platform, method, error)

Logs API errors consistently.

@staticmethod
def _log_api_error(platform, method, error)