chess-v2 / app.py
christopher's picture
Update app.py
dbb3e77 verified
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import chess
from datasets import load_dataset
import time
from chess_search.sparse.bitmap import BitmapIndex
from chess_search.utils import position_to_tokens, replay_moves
dset = load_dataset("Lichess/chess-puzzles", split="train")
puzzle_lookup = {row["PuzzleId"]: i for i, row in enumerate(dset)}
idx = BitmapIndex.load("index")
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
@app.get("/")
def read_root(request: Request):
return templates.TemplateResponse(request=request, name="index.html")
@app.post("/search")
async def search(data: dict):
start = time.time()
board = chess.Board(data["fen"])
tokens = position_to_tokens(board)
matches = idx.query(tokens)
resolved = idx.resolve(matches)
seen_puzzles = {}
for puzzle_id, move_idx in resolved:
if puzzle_id not in seen_puzzles:
seen_puzzles[puzzle_id] = move_idx
results = []
for puzzle_id, move_idx in seen_puzzles.items():
row = dset[puzzle_lookup[puzzle_id]]
boards = replay_moves(row["FEN"], row["Moves"].split())
matched_board = boards[move_idx]
results.append({
"PuzzleId": row["PuzzleId"],
"FEN": matched_board.fen(),
"Moves": row["Moves"],
"Rating": row["Rating"],
"Popularity": row["Popularity"],
"Themes": row["Themes"],
"MatchedMove": move_idx,
})
elapsed_ms = (time.time() - start) * 1000
return {"count": len(results), "results": results, "time_ms": elapsed_ms}