Skip to main content

qcs_sdk/
client.rs

1use pyo3::{exceptions::PyValueError, pyfunction};
2use qcs_api_client_common::configuration::{
3    AuthServer, ClientConfigurationBuilder, ClientConfigurationBuilderError, ClientCredentials,
4    ExternallyManaged, OAuthSession, RefreshToken,
5};
6use rigetti_pyo3::{
7    create_init_submodule, py_function_sync_async, py_wrap_error, py_wrap_type,
8    pyo3::{
9        conversion::IntoPy, exceptions::PyRuntimeError, pyclass::CompareOp, pymethods, PyObject,
10        PyResult, Python,
11    },
12    wrap_error, PyWrapper, ToPythonError,
13};
14
15use qcs::client::{self, Qcs};
16
17create_init_submodule! {
18    classes: [
19        PyQcsClient,
20        OAuthSession,
21        AuthServer,
22        RefreshToken,
23        ClientCredentials,
24        ExternallyManaged
25    ],
26    errors: [
27        LoadClientError,
28        BuildClientError
29    ],
30}
31
32wrap_error!(RustLoadClientError(client::LoadError));
33py_wrap_error!(client, RustLoadClientError, LoadClientError, PyRuntimeError);
34
35wrap_error!(RustBuildClientError(ClientConfigurationBuilderError));
36
37py_wrap_error!(
38    client,
39    RustBuildClientError,
40    BuildClientError,
41    PyRuntimeError
42);
43
44py_wrap_type! {
45    PyQcsClient(Qcs) as "QCSClient";
46}
47
48impl PyQcsClient {
49    pub fn get_or_create_client(client: Option<Self>) -> Qcs {
50        match client {
51            Some(client) => client.into(),
52            None => Qcs::load(),
53        }
54    }
55}
56
57impl PartialEq for PyQcsClient {
58    fn eq(&self, other: &Self) -> bool {
59        format!("{:?}", self.0) == format!("{:?}", other.0)
60    }
61}
62
63#[pymethods]
64impl PyQcsClient {
65    #[new]
66    #[pyo3(signature = (
67        /,
68        oauth_session = None,
69        api_url = None,
70        grpc_api_url = None,
71        quilc_url = None,
72        qvm_url = None
73    ))]
74    pub fn new(
75        oauth_session: Option<OAuthSession>,
76        api_url: Option<String>,
77        grpc_api_url: Option<String>,
78        quilc_url: Option<String>,
79        qvm_url: Option<String>,
80    ) -> PyResult<Self> {
81        let mut builder = ClientConfigurationBuilder::default();
82        if let Some(session) = oauth_session {
83            builder.oauth_session(Some(session));
84        }
85        if let Some(api_url) = api_url {
86            builder.api_url(api_url);
87        }
88        if let Some(grpc_api_url) = grpc_api_url {
89            builder.grpc_api_url(grpc_api_url);
90        }
91        if let Some(quilc_url) = quilc_url {
92            builder.quilc_url(quilc_url);
93        }
94        if let Some(qvm_url) = qvm_url {
95            builder.qvm_url(qvm_url);
96        }
97        let client = builder
98            .build()
99            .map(Qcs::with_config)
100            .map_err(RustBuildClientError::from)
101            .map_err(RustBuildClientError::to_py_err)?;
102
103        Ok(Self(client))
104    }
105
106    #[staticmethod]
107    #[pyo3(signature = (/, profile_name = None))]
108    fn load(profile_name: Option<String>) -> PyResult<Self> {
109        Ok(match profile_name {
110            Some(profile_name) => Qcs::with_profile(profile_name)
111                .map(PyQcsClient)
112                .map_err(RustLoadClientError)
113                .map_err(RustLoadClientError::to_py_err)?,
114            None => Self(Qcs::load()),
115        })
116    }
117
118    #[getter]
119    pub fn api_url(&self) -> String {
120        self.as_ref().get_config().api_url().to_string()
121    }
122
123    #[getter]
124    pub fn grpc_api_url(&self) -> String {
125        self.as_ref().get_config().grpc_api_url().to_string()
126    }
127
128    #[getter]
129    pub fn quilc_url(&self) -> String {
130        self.as_ref().get_config().quilc_url().to_string()
131    }
132
133    #[getter]
134    pub fn qvm_url(&self) -> String {
135        self.as_ref().get_config().qvm_url().to_string()
136    }
137
138    #[getter]
139    pub fn oauth_session(&self, py: Python<'_>) -> PyResult<OAuthSession> {
140        py_get_oauth_session(py, self.clone())
141    }
142
143    fn __richcmp__(&self, other: &Self, op: CompareOp, py: Python<'_>) -> PyObject {
144        match op {
145            CompareOp::Eq => (self == other).into_py(py),
146            CompareOp::Ne => (self != other).into_py(py),
147            _ => py.NotImplemented(),
148        }
149    }
150}
151
152py_function_sync_async! {
153    #[pyfunction]
154    async fn get_oauth_session(client: PyQcsClient) -> PyResult<OAuthSession> {
155        client.as_inner().get_config().oauth_session().await.map_err(|e| PyValueError::new_err(e.to_string()))
156
157    }
158}