Skip to main content

lichess_api/api/
external_engine.rs

1//! Register and use an external engine: a chess engine running on the user's
2//! own machine, made available for cloud analysis (e.g. from the Lichess
3//! analysis board) via a provider/secret handshake.
4//!
5//! Listing, creating, fetching, updating, and deleting engine registrations
6//! ([`list_external_engines`](LichessApi::list_external_engines),
7//! [`create_external_engine`](LichessApi::create_external_engine),
8//! [`get_external_engine`](LichessApi::get_external_engine),
9//! [`update_external_engine`](LichessApi::update_external_engine),
10//! [`delete_external_engine`](LichessApi::delete_external_engine)) require a
11//! bearer token with the `engine:read` or `engine:write` scope and talk to
12//! the regular Lichess host. Requesting and providing analysis
13//! ([`analyse_with_external_engine`](LichessApi::analyse_with_external_engine),
14//! [`acquire_analysis_request`](LichessApi::acquire_analysis_request),
15//! [`submit_analysis`](LichessApi::submit_analysis)) instead use the engine's
16//! own client/provider secrets for auth and are served from a separate host,
17//! [`Domain::Engine`](crate::model::Domain::Engine).
18
19use futures::stream::StreamExt;
20
21use crate::client::LichessApi;
22use crate::error::Result;
23use crate::model::external_engine::*;
24
25impl LichessApi<reqwest::Client> {
26    pub async fn list_external_engines(&self) -> Result<Vec<ExternalEngine>> {
27        self.get_single_model(list::GetRequest::new()).await
28    }
29
30    pub async fn create_external_engine(
31        &self,
32        request: impl Into<create::PostRequest>,
33    ) -> Result<ExternalEngine> {
34        self.get_single_model(request.into()).await
35    }
36
37    pub async fn get_external_engine(
38        &self,
39        request: impl Into<id::GetRequest>,
40    ) -> Result<ExternalEngine> {
41        self.get_single_model(request.into()).await
42    }
43
44    pub async fn update_external_engine(
45        &self,
46        request: impl Into<update::PutRequest>,
47    ) -> Result<ExternalEngine> {
48        self.get_single_model(request.into()).await
49    }
50
51    pub async fn delete_external_engine(
52        &self,
53        request: impl Into<delete::DeleteRequest>,
54    ) -> Result<bool> {
55        self.get_ok(request.into()).await
56    }
57
58    /// This method currently returns a 503 error (Service Unavailable) from the Lichess API
59    pub async fn analyse_with_external_engine(
60        &self,
61        request: impl Into<analyse::PostRequest>,
62    ) -> Result<impl StreamExt<Item = Result<analyse::AnalysisResponse>>> {
63        self.get_streamed_models(request.into()).await
64    }
65
66    pub async fn acquire_analysis_request(
67        &self,
68        request: impl Into<acquire_analysis::PostRequest>,
69    ) -> Result<Option<acquire_analysis::AcquireAnalysisResponse>> {
70        let mut stream = self.get_streamed_models(request.into()).await?;
71        // The response is a stream of 0 or 1 items, so we can just take the first item
72        (stream.next().await).transpose()
73    }
74
75    pub async fn submit_analysis(
76        &self,
77        request: impl Into<submit_analysis::PostRequest>,
78    ) -> Result<()> {
79        self.get_empty(request.into()).await
80    }
81}