← Back to the cube

Python API

Add Rubikoslav to a Python project, pass it normal cube notation, and get back a route checked by the native C++ engine.

Install it

Use either command in your project. Published wheels already include the compiled C++ extension.

pip install rubikoslav

# or, in a uv project
uv add rubikoslav

Solve normal notation

The main API manages the cube state for you. Pass a string such as R U F2.

from rubikoslav import Rubikoslav

result = Rubikoslav().solve_scramble("R U F2")

if result.success:
    print(result.moves)
    print(result.optimal)
else:
    raise RuntimeError(result.error)

The first solve prepares a local search cache. Later solves reuse it.

What happens during a solve

  1. solve_scramble() builds the position with the native C++ cube.
  2. Python translates the state and searches for a route of at most 20 half-turn-metric moves.
  3. C++ replays the route and rejects it if the cube does not finish solved.
  4. The result includes the moves, elapsed time, backend, and whether the shortest route was proven.

Use a raw cube state

If your integration already tracks the 48 movable stickers, call the lower-level method directly.

from rubikoslav import Rubikoslav

result = Rubikoslav().solve(state)
if not result.success:
    raise RuntimeError(result.error)

state needs 48 integers from 0 through 5, with eight of each color.

Call the local HTTP endpoint

Start the app with uv run rubikoslav --no-open. The server accepts the same payload as the browser.

import json
from urllib.request import Request, urlopen
from rubikoslav import CuboslavWrapper

history = ["R", "U"]
cube = CuboslavWrapper()
for move in history:
    cube.move(move)

body = json.dumps({
    "state": list(cube.getCube()),
    "history": history,
}).encode()

request = Request(
    "http://127.0.0.1:4173/api/solve",
    data=body,
    headers={"Content-Type": "application/json"},
)

with urlopen(request) as response:
    print(json.load(response))

state is required and history is optional. If the two-second Python search times out, Rubikoslav can use the reversed history only after C++ verifies it and only when it is no longer than 20 moves. The TypeScript visualizer calls this endpoint; it does not contain a separate solver.