Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement /api/external_engine endpoints #58

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@ Changelog
To be released
--------------

* Add ``
* Add::
client.external_engine.get
client.external_engine.get_by_id
client.external_engine.create
client.external_engine.update
client.external_engine.delete
* Add::
client.tournaments.edit_swiss
client.tournaments.get_swiss
client.tournaments.join_swiss
client.tournaments.stream_swiss_results
client.tournaments.schedule_swiss_next_round
client.tournaments.terminate_swiss
client.tournaments.withdraw_swiss``
client.tournaments.withdraw_swiss
* Add ``client.puzzles.create_race``
* Add ``client.users.get_by_autocomplete``

Expand Down
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ Most of the API is available:
client.explorer.get_player_games
client.explorer.stream_player_games

client.external_engine.get
client.external_engine.get_by_id
client.external_engine.create
client.external_engine.update
client.external_engine.delete

client.games.export
client.games.export_ongoing_by_player
client.games.export_by_player
Expand Down
4 changes: 4 additions & 0 deletions berserk/clients/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from .tablebase import Tablebase
from .opening_explorer import OpeningExplorer
from .bulk_pairings import BulkPairings
from .external_engine import ExternalEngine

__all__ = [
"Client",
Expand All @@ -43,6 +44,7 @@
"TV",
"Tablebase",
"BulkPairings",
"ExternalEngine",
]


Expand All @@ -67,6 +69,7 @@ class Client(BaseClient):
- :class:`tv <berserk.clients.TV>` - get information on tv channels and games
- :class:`tablebase <berserk.clients.Tablebase>` - lookup endgame tablebase
- :class:`bulk_pairings <berserk.clients.BulkPairing>` - manage bulk pairings
- :class: `external_engine <berserk.clients.ExternalEngine>` - manage external engines

:param session: request session, authenticated as needed
:param base_url: base API URL to use (if other than the default)
Expand Down Expand Up @@ -106,3 +109,4 @@ def __init__(
self.tablebase = Tablebase(session, tablebase_url)
self.opening_explorer = OpeningExplorer(session, explorer_url)
self.bulk_pairings = BulkPairings(session, base_url)
self.external_engine = ExternalEngine(session, base_url)
114 changes: 114 additions & 0 deletions berserk/clients/external_engine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
from __future__ import annotations

from typing import List, cast

from .base import BaseClient


class ExternalEngine(BaseClient):
"""Client for external engine related endpoints."""

def get(self) -> List[ExternalEngine]:
"""Lists all external engines that have been registered for the user, and the credentials required to use them.

Requires OAuth2 authorization.

:return: info about the external engines
"""
path = "/api/external-engine"
return cast(List[ExternalEngine], self._r.get(path))

def get_by_id(self, engine_id: str) -> ExternalEngine:
"""Get properties and credentials of an external engine.

Requires OAuth2 authorization.

:param engine_id: external engine ID
:return: info about the external engine
"""
path = f"/api/external-engine/{engine_id}"
return cast(ExternalEngine, self._r.get(path))

def create(
self,
name: str,
max_threads: int,
max_hash_table_size: int,
default_depth: int,
provider_secret: str,
variants: List[str] | None = None,
provider_data: str | None = None,
) -> ExternalEngine:
"""Registers a new external engine for the user.

Requires OAuth2 authorization.

:param name: engine display name
:param max_threads: maximum number of available threads
:param max_hash_table_size: maximum available hash table size, in MiB
:param default_depth: estimated depth of normal search
:param provider_secret: random token that used to wait for analysis requests and provide analysis
:param variants: list of supported chess variants
:param provider_data: arbitrary data that engine provider can use for identification or bookkeeping
:return: info about the external engine
"""
path = "/api/external-engine"
payload = {
"name": name,
"maxThreads": max_threads,
"maxHash": max_hash_table_size,
"defaultDepth": default_depth,
"variants": variants,
"providerSecret": provider_secret,
"providerData": provider_data,
}
return cast(ExternalEngine, self._r.post(path=path, payload=payload))

def update(
self,
engine_id: str,
name: str,
max_threads: int,
max_hash_table_size: int,
default_depth: int,
provider_secret: str,
variants: List[str] | None = None,
provider_data: str | None = None,
) -> ExternalEngine:
"""Updates the properties of an external engine.

Requires OAuth2 authorization.

:param engine_id: engine ID
:param name: engine display name
:param max_threads: maximum number of available threads
:param max_hash_table_size: maximum available hash table size, in MiB
:param default_depth: estimated depth of normal search
:param provider_secret: random token that used to wait for analysis requests and provide analysis
:param variants: list of supported chess variants
:param provider_data: arbitrary data that engine provider can use for identification or bookkeeping
:return: info about the external engine
"""
path = f"/api/external-engine/{engine_id}"
payload = {
"name": name,
"maxThreads": max_threads,
"maxHash": max_hash_table_size,
"defaultDepth": default_depth,
"variants": variants,
"providerSecret": provider_secret,
"providerData": provider_data,
}
return cast(
ExternalEngine, self._r.request(method="PUT", path=path, payload=payload)
)

def delete(self, engine_id: str) -> None:
"""Unregisters an external engine.

Requires OAuth2 authorization.

:param engine_id: engine ID
"""
path = f"/api/external-engine/{engine_id}"
self._r.request("DELETE", path)
3 changes: 2 additions & 1 deletion berserk/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from .account import AccountInformation, Perf, Preferences, Profile, StreamerInfo
from .bulk_pairings import BulkPairing, BulkPairingGame
from .common import ClockConfig, LightUser, OnlineLightUser
from .common import ClockConfig, ExternalEngine, LightUser, OnlineLightUser
from .puzzles import PuzzleRace
from .opening_explorer import (
OpeningExplorerRating,
Expand All @@ -19,6 +19,7 @@
"BulkPairing",
"BulkPairingGame",
"ClockConfig",
"ExternalEngine",
"LightUser",
"OnlineLightUser",
"CurrentTournaments",
Expand Down
21 changes: 21 additions & 0 deletions berserk/types/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,27 @@ class ClockConfig(TypedDict):
increment: int


class ExternalEngine(TypedDict):
# Engine ID
id: str
# Engine display name
name: str
# Secret token that can be used to request analysis
clientSecret: str
# User this engine has been registered for
userId: str
# Max number of available threads
maxThreads: int
# Max available hash table size, in MiB
maxHash: int
# Estimated depth of normal search
defaultDepth: int
# List of supported chess variants
variants: str
# Arbitrary data that engine provider can use for identification or bookkeeping
providerData: NotRequired[str]


Color: TypeAlias = Literal["white", "black"]

GameType: TypeAlias = Literal[
Expand Down