This release is a pre-release and may not be stable for production use.
Pychess External Engine
Local native-engine analysis for the Pychess website.
Status
The paired native HTTP API is implemented. It launches configured UCI executables,
discovers capabilities, and owns serialized searches with structured MultiPV events
and bounded cancellation/restart/idle handling. An isolated pyffish worker validates
positions, histories and PVs with geometry and material limits. Custom definitions
are checked with the native engine, loaded before discovery, and replaced on
rules-hash changes. The sibling Pychess checkout now provides source selection,
pairing and native evaluation/PV display for single-board analysis. The initial package release is version 0.1.0a1. Website deployment is separate.
Start with the installation and usage guide.
The design and implementation checklist are maintained in
Pychess's external-engine plan
in the Pychess integration branch. Its repository path is docs/external-engine.md in
pychess-variants.
Design
One Python application runs on the user's computer and combines a local HTTP bridge,
UCI subprocess management, and pyffish rules validation. The Pychess analysis page
connects directly to the bridge through a paired loopback connection and displays
streamed evaluations from the user's native engine.
No additional Heroku process or public broker is required. Engine executables,
networks, resource limits, and pairing are configured locally. Native engines perform
the search; pyffish validates positions, histories, and principal variations.
The first implementation step is to prove HTTPS-to-loopback streaming and cancellation in supported browsers. Ordinary single-board Fairy-Stockfish analysis comes first, with exact custom rules included. Alice rules are included by default, with a dedicated locally configured native engine adapter. Two-board analysis, hidden-information variants, and USI/UCCI adapters remain deferred.
Run with uvx
Install uv once, then run this first alpha release with a supported interpreter:
uvx --python 3.13 pychess-external-engine@0.1.0a1 \
--engine /path/to/fairy-stockfish --setoption 'Use NNUE' false
Both pyffish and pyffish-alice are installed automatically. The native executables
and networks are still supplied locally; engine download/setup automation is planned.
For Alice search, add --alice-engine /path/to/alice-stockfish and its
--alice-setoption EvalFile /path/to/Alice_v1.nnue option. Default installations
include Alice rules even when only the ordinary engine is configured.
Development installation and engine discovery
Python 3.11–3.14 is the tested range. Clean-install evidence is recorded in the compatibility matrix. The verified OS is Linux x86_64; other operating systems remain unverified.
uv sync --extra dev
uv run pychess-external-engine --engine /path/to/fairy-stockfish --check-engine
To include site-defined variants and configure local engine options:
uv run pychess-external-engine --engine /path/to/fairy-stockfish \
--setoption VariantPath /path/to/pychess-variants/variants.ini \
--setoption 'Use NNUE' false --check-engine
The executable is launched with an argument array, without a shell. Use repeated
--engine-arg options for executable arguments and --max-threads/--max-hash for
local resource ceilings. Discovery applies configured options, waits for readiness,
then re-queries UCI capabilities so newly loaded custom variants are advertised.
Search-controlled options such as Threads and UCI_Variant cannot be configured with
--setoption; other configured options must be advertised by the engine.
Start the local bridge (without --check-engine):
uv run pychess-external-engine --engine /path/to/fairy-stockfish \
--setoption 'Use NNUE' false
It binds to 127.0.0.1:9670 and prints a temporary pairing token. Restart to rotate
the token. Use --port or repeated --allow-origin to configure local access;
explicit origins replace the default Pychess origins. --max-search-seconds and
--idle-seconds set the search ceiling and idle process lifetime. Networks and their
paths are configured locally through engine options; the example disables NNUE.
The HTTP contract is in docs/protocol.md. In the updated Pychess
analysis page, open engine settings, enter the address/token and choose Connect.
Enable analysis with the existing engine switch. Disconnect switches to the browser
engine; Forget also removes the browser's saved pairing token. The development
browser probe can exercise the native API independently:
uv run python -m tools.browser_probe --browser edge \
--engine /path/to/fairy-stockfish --setoption 'Use NNUE' false
The probe runs its own temporary bridge and browser profile. Chromium and Edge on Linux pass native streaming, competing tabs, abort/tab-close cleanup and permission denial from the deployed HTTPS analysis page. Firefox's recorded check used the transport prototype; a native Firefox UI check remains pending.
Verify the integrated UI using a built sibling Pychess checkout and its development virtualenv (including its Mongo mock and Playwright dependencies):
uv run python -m tools.ui_probe --browser edge --pychess ../pychess-variants \
--engine /path/to/fairy-stockfish --setoption 'Use NNUE' false
This probe starts a Pychess test server with an in-memory database and the real local
bridge. It serves the checkout through a synthetic HTTPS origin using Playwright
routing; it does not modify the deployed website or disable browser security.
It checks native PV navigation, competing tabs, tab closure, reconnect, forget,
permission denial, and mobile/desktop light/dark settings. Use --variant orda
for exact site rules or --variant cwda --without-wasm to verify independence from
browser search. Add --restart-bridge to verify shutdown, token rotation and re-pairing.
Use --variant alice --expect-unsupported without an Alice engine to verify
capability rejection in the UI. See browser compatibility for evidence.
Verify Study chapter changes, historical rules snapshots, Practice ownership, and computer permissions with a temporary Study database:
uv run python -m tools.study_probe --browser edge --pychess ../pychess-variants \
--engine /path/to/fairy-stockfish --setoption 'Use NNUE' false
Optional Alice engine
Alice rules validation is included in every installation. Configure a separate Alice-capable UCI engine to enable native Alice search:
uv sync --extra dev
uv run pychess-external-engine --engine /path/to/fairy-stockfish \
--setoption 'Use NNUE' false --alice-engine /path/to/alice-stockfish \
--alice-setoption EvalFile /path/to/Alice_v1.nnue
Alice options and executable arguments use --alice-setoption and --alice-engine-arg.
They stay on the local computer. Startup requires the Alice rules library, an engine
advertising alice, and a shallow search returning a legal best move. A missing or
incompatible Alice configuration stops startup with an error; omit Alice options to
run the ordinary engine alone. The bridge closes the previous native process before
switching engines, with one search owner shared across all variants and tabs.
Alice uses fixed rules, compact FEN with | before looking-glass-board pieces, and
ordinary coordinate move tokens. The adapter validates full move histories and PVs
with pinned pyffish-alice 0.0.3. Alice custom definitions, legacy 16-wide FEN input,
and Alice Chess960 are outside this adapter's capability. NNUE files must match the
chosen Alice engine. The tested Alice-Stockfish 1.0 binary uses Alice_v1.nnue in
Legacy evaluation mode; disabling its NNUE selects zero diagnostic evaluation,
which is useful for lifecycle tests but not meaningful positional evaluation.
To repeat the integrated Edge check:
uv run python -m tools.ui_probe --browser edge --variant alice --without-wasm \
--engine /path/to/fairy-stockfish --setoption 'Use NNUE' false \
--alice-engine /path/to/alice-stockfish \
--alice-setoption EvalFile /path/to/Alice_v1.nnue
For native unit checks, add PYCHESS_TEST_ALICE_ENGINE and optionally
PYCHESS_TEST_ALICE_NETWORK alongside PYCHESS_TEST_ENGINE. Without the network
variable, Alice tests use zero diagnostic evaluation.
Build and repeat clean installation checks from this checkout:
uv build
PYCHESS_TEST_ENGINE=/path/to/fairy-stockfish \
PYCHESS_TEST_ALICE_ENGINE=/path/to/alice-stockfish \
PYCHESS_TEST_ALICE_NETWORK=/path/to/Alice_v1.nnue \
uv run python -m tools.install_probe \
--artifact dist/pychess_external_engine-0.1.0a1-py3-none-any.whl
The probe checks fresh Linux environments for Python 3.11–3.14, installed-code
imports including both required rules libraries, unit/native tests and the installed
CLI's pairing/shutdown. Use repeated
--python to select interpreters, or provide the source archive to check a source
install. The wheel contains the application and license/notice, while the source
archive also includes tests, probes, documentation and the lockfile.
Development checks:
uv run ruff format --target-version py313 --check .
uv run ruff check .
uv run pyrefly check
uv run python -m unittest discover -s tests -v
Run the native smoke checks with your Fairy-Stockfish executable:
PYCHESS_TEST_ENGINE=/path/to/fairy-stockfish \
uv run python -m unittest discover -s tests -v
These checks disable NNUE and search trusted starting positions at depth 2 with
MultiPV 2 for Chess, Shogi, Xiangqi, and Grand Chess. They verify legal best moves
and PV prefixes with pyffish. Fake-engine tests cover cancellation, delayed stop
output, competing ownership, hung engines, crashes, output bounds, and idle races.
Production rules validation uses a separate process for each search, keeping custom
registrations and native failures out of the bridge process. Tests cover exact rules
hashes, inherited snapshots, Chess960, pockets, promotion state, extended coordinates,
S-Chess gating and malformed inputs. Native-engine compatibility with supplied custom
definitions is checked separately before search. The pinned library's supported
rule-name schema also rejects keys it would otherwise silently ignore. Historical
custom rules replace local VariantPath definitions for that search. A changed rules
hash restarts the native engine to avoid stale or accumulating registrations.
See verified variant/engine coverage for the representative native and UI checks and their limits.
Source is licensed under AGPL-3.0-or-later. See NOTICE.md and LICENSE for upstream attribution and distribution notes. Engines and networks are user-supplied.
Transport prototype
Run from this checkout with Python 3.11 or later and aiohttp installed:
uv run --with aiohttp python -m tools.transport_probe
The prototype binds only to 127.0.0.1:9670, prints a temporary pairing token,
and allows https://www.pychess.org and https://pychess.org. Restarting rotates
the token. Use --port or repeated --allow-origin options to change local settings.
Specifying allowed origins replaces the defaults.
Requests to GET /v1/capabilities and POST /v1/analyse require an allowed Origin
and Authorization: Bearer <pairing-token>. The analysis request contains
protocolVersion: 1, sessionId, and searchId. Its streamed results are explicitly
marked prototype: true and must never be used as chess evaluations.
Only one stream can be active. Concurrent requests receive 409 engine_busy;
aborting the active request releases ownership. Streams have a 30-second limit.
This prototype establishes transport semantics; the complete engine protocol is
specified in docs/protocol.md for implementation in phases 2–4.
See browser compatibility for the verified Chromium transport, Firefox's successful headed permission check, and the Linux WebKit limitation. The browser probe uses a temporary local application and a fresh browser profile:
python -m tools.browser_probe --browser chromium
python -m tools.browser_probe --browser firefox --headed --manual-permission
These commands require playwright in addition to aiohttp; install its Firefox
test browser with python -m playwright install firefox before the headed check.
Run the transport tests:
uv run --with aiohttp python -m unittest discover -s tests -v
References
Preserve upstream licenses and attribution when adapting implementation code from these projects.
Metadata
Release files for pychess-external-engine 0.1.0a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pychess_external_engine-0.1.0a1.tar.gz | 169.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pychess_external_engine-0.1.0a1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 214.9 kB
Release files / pychess_external_engine-0.1.0a1.tar.gz
| Download URL | pychess_external_engine-0.1.0a1.tar.gz |
|---|---|
| Size | 169.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a5576f3d6dc7c4fa1d72aac671f9b406cd2535453360d1da3ed9f6af50822c76
|
|
BLAKE2b-256 checksum How to use checksums |
451bb9d92533d806819c5d4674c16d985fabf24a2c1980e203f0d90b82e8da72
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / pychess_external_engine-0.1.0a1-py3-none-any.whl
| Download URL | pychess_external_engine-0.1.0a1-py3-none-any.whl |
|---|---|
| Size | 45.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2a95a4d4839a5bccf2736d7fd21de5f2cb426e97ac9ea37176f07a2d6535b2a7
|
|
BLAKE2b-256 checksum How to use checksums |
198062df524cd00183cb34b8bef3ae743a95834d3d64e04f6ae91c6371492b52
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|