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}