Skip to content

Commit

Permalink
Implement /api/cloud-eval endpoint (#62)
Browse files Browse the repository at this point in the history
* add cloud-eval endpoint

* oop small typo

* fix the uri

* should be a yaml

* rename file to the correct one and remove unused imports

* remove stray q

* tweaks: changelog + explanations precede the field

---------

Co-authored-by: kraktus <[email protected]>
  • Loading branch information
Anupya and kraktus authored Nov 3, 2023
1 parent 7f94f6e commit ee65d42
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 0 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
Changelog
=========

To be released
--------------

* Added::

client.analysis.get_cloud_evaluation

Thanks to @Anupya for their contributions to this release.

v0.13.1 (2023-11-02)
--------------------

Expand Down
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ Most of the API is available:
client.account.set_kid_mode
client.account.upgrade_to_bot
client.analysis.get_cloud_evaluation
client.board.stream_incoming_events
client.board.seek
client.board.stream_game_state
Expand Down
4 changes: 4 additions & 0 deletions berserk/clients/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import requests

from .analysis import Analysis
from .base import BaseClient
from .account import Account
from .users import Users
Expand All @@ -26,6 +27,7 @@

__all__ = [
"Account",
"Analysis",
"Board",
"Bots",
"Broadcasts",
Expand Down Expand Up @@ -54,6 +56,7 @@ class Client(BaseClient):
All endpoints are namespaced into the clients below:
- :class:`account <berserk.clients.Account>` - managing account information
- :class:`account <berserk.clients.Analysis>` - getting information about position analysis
- :class:`bots <berserk.clients.Bots>` - performing bot operations
- :class:`broadcasts <berserk.clients.Broadcasts>` - getting and creating broadcasts
- :class:`challenges <berserk.clients.Challenges>` - using challenges
Expand Down Expand Up @@ -91,6 +94,7 @@ def __init__(
session = session or requests.Session()
super().__init__(session, base_url)
self.account = Account(session, base_url)
self.analysis = Analysis(session, base_url)
self.users = Users(session, base_url)
self.relations = Relations(session, base_url)
self.teams = Teams(session, base_url)
Expand Down
31 changes: 31 additions & 0 deletions berserk/clients/analysis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from __future__ import annotations

from typing import cast

from ..types import Variant
from .base import BaseClient
from ..types.analysis import PositionEvaluation


class Analysis(BaseClient):
"""Client for analysis-related endpoints."""

def get_cloud_evaluation(
self,
fen: str,
num_variations: int = 1,
variant: Variant = "standard",
) -> PositionEvaluation:
"""Get the cached evaluation of a position, if available.
Opening positions have more chances of being available. There are about 15 million positions in the database.
Up to 5 variations may be available. Variants are supported.
:param fen: FEN of a position
:param num_variations: number of variations
:param variant: game variant to use
:return: cloud evaluation of a position
"""
path = "/api/cloud-eval"
params = {"fen": fen, "multiPv": num_variations, "variant": variant}
return cast(PositionEvaluation, self._r.get(path=path, params=params))
20 changes: 20 additions & 0 deletions berserk/types/analysis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from typing import List

from typing_extensions import TypedDict


class PrincipleVariation(TypedDict):
moves: str
"""Centipawn (cp) is the unit of measure used in chess as representation of the advantage. A centipawn is 1/100th
of a pawn. This value can be used as an indicator of the quality of play. The fewer centipawns one loses per move,
the stronger the play.
"""
cp: int


class PositionEvaluation(TypedDict):
fen: str
knodes: int
depth: int
""" Principle Variation (pv) is a variation composed of the "best" moves (in the opinion of the engine)."""
pvs: List[PrincipleVariation]
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
interactions:
- request:
body: null
headers:
Accept:
- application/json
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
User-Agent:
- python-requests/2.31.0
method: GET
uri: https://lichess.org/api/cloud-eval?fen=rnbqkbnr%2Fppp1pppp%2F8%2F3pP3%2F8%2F8%2FPPPP1PPP%2FRNBQKBNR+b+KQkq+-+0+2&multiPv=1&variant=standard
response:
body:
string: '{"fen": "rnbqkbnr/ppp1pppp/8/3pP3/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 2","knodes":13683,"depth":22,"pvs":[{"moves":"c8f5 d2d4 e7e6 g1f3 g8e7 c1e3 c7c5 d4c5 e7c6 b1c3","cp":-13}]}'
headers:
Access-Control-Allow-Headers:
- Origin, Authorization, If-Modified-Since, Cache-Control, Content-Type
Access-Control-Allow-Methods:
- OPTIONS, GET, POST, PUT, DELETE
Access-Control-Allow-Origin:
- '*'
Connection:
- keep-alive
Content-Type:
- application/json
Date:
- Thu, 02 Nov 2023 21:25:59 GMT
Permissions-Policy:
- interest-cohort=()
Server:
- nginx
Strict-Transport-Security:
- max-age=63072000; includeSubDomains; preload
Transfer-Encoding:
- chunked
Vary:
- Origin
X-Frame-Options:
- DENY
content-length:
- '6450'
status:
code: 200
message: OK
version: 1
16 changes: 16 additions & 0 deletions tests/clients/test_analysis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import pytest

from berserk import Client

from berserk.types.analysis import PositionEvaluation
from utils import validate, skip_if_older_3_dot_10


class TestAnalysis:
@skip_if_older_3_dot_10
@pytest.mark.vcr
def test_get_cloud_evaluation(self):
res = Client().analysis.get_cloud_evaluation(
fen="rnbqkbnr/ppp1pppp/8/3pP3/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 2",
)
validate(PositionEvaluation, res)

0 comments on commit ee65d42

Please sign in to comment.