qcs_api_client_openapi/apis/
deployments_api.rs1use super::{ContentType, Error, configuration};
26use crate::{apis::ResponseContent, models};
27use ::qcs_api_client_common::backoff::{
28 BackoffBuilder, ExponentialBackoff, duration_from_io_error, duration_from_reqwest_error,
29 duration_from_response,
30};
31#[cfg(feature = "tracing")]
32use qcs_api_client_common::configuration::tokens::TokenRefresher;
33use qcs_dependencies_client::reqwest::{self, StatusCode};
34use serde::{Deserialize, Serialize};
35
36#[cfg(feature = "clap")]
37#[allow(unused, reason = "not used in all templates, but required in some")]
38use ::{miette::IntoDiagnostic as _, qcs_api_client_common::clap_utils::JsonMaybeStdin};
39
40#[cfg(feature = "clap")]
42#[derive(Debug, clap::Args)]
43pub struct GetEndpointAccessorsClapParams {
44 #[arg(long)]
45 pub endpoint_id: String,
46}
47
48#[cfg(feature = "clap")]
49impl GetEndpointAccessorsClapParams {
50 pub async fn execute(
51 self,
52 configuration: &configuration::Configuration,
53 ) -> Result<models::ListQuantumProcessorAccessorsResponse, miette::Error> {
54 get_endpoint_accessors(configuration, self.endpoint_id.as_str())
55 .await
56 .into_diagnostic()
57 }
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
62#[serde(untagged)]
63pub enum GetEndpointAccessorsError {
64 Status422(models::ValidationError),
65 DefaultResponse(models::Error),
66 UnknownValue(serde_json::Value),
67}
68
69async fn get_endpoint_accessors_inner(
70 configuration: &configuration::Configuration,
71 backoff: &mut ExponentialBackoff,
72 endpoint_id: &str,
73) -> Result<models::ListQuantumProcessorAccessorsResponse, Error<GetEndpointAccessorsError>> {
74 let local_var_configuration = configuration;
75 let p_path_endpoint_id = endpoint_id;
77
78 let local_var_client = &local_var_configuration.client;
79
80 let local_var_uri_str = format!(
81 "{}/v1/endpoints/{endpoint_id}/accessors",
82 local_var_configuration.qcs_config.api_url(),
83 endpoint_id = crate::apis::urlencode(p_path_endpoint_id)
84 );
85 let mut local_var_req_builder =
86 local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
87
88 #[cfg(feature = "tracing")]
89 {
90 let local_var_do_tracing = local_var_uri_str
93 .parse::<::url::Url>()
94 .ok()
95 .is_none_or(|url| {
96 configuration
97 .qcs_config
98 .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
99 });
100
101 if local_var_do_tracing {
102 ::tracing::debug!(
103 url=%local_var_uri_str,
104 method="GET",
105 "making get_endpoint_accessors request",
106 );
107 }
108 }
109
110 {
113 use qcs_api_client_common::configuration::TokenError;
114
115 #[allow(
116 clippy::nonminimal_bool,
117 clippy::eq_op,
118 reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
119 )]
120 let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
121
122 let token = local_var_configuration
123 .qcs_config
124 .get_bearer_access_token()
125 .await;
126
127 if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
128 #[cfg(feature = "tracing")]
130 tracing::debug!(
131 "No client credentials found, but this call does not require authentication."
132 );
133 } else {
134 local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
135 }
136 }
137
138 let local_var_req = local_var_req_builder.build()?;
139 let local_var_resp = local_var_client.execute(local_var_req).await?;
140
141 let local_var_status = local_var_resp.status();
142 let local_var_raw_content_type = local_var_resp
143 .headers()
144 .get("content-type")
145 .and_then(|v| v.to_str().ok())
146 .unwrap_or("application/octet-stream")
147 .to_string();
148 let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
149
150 if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
151 let local_var_content = local_var_resp.text().await?;
152 match local_var_content_type {
153 ContentType::Json => serde_path_to_error::deserialize(
154 &mut serde_json::Deserializer::from_str(&local_var_content),
155 )
156 .map_err(Error::from),
157 ContentType::Text => Err(Error::InvalidContentType {
158 content_type: local_var_raw_content_type,
159 return_type: "models::ListQuantumProcessorAccessorsResponse",
160 }),
161 ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
162 content_type: unknown_type,
163 return_type: "models::ListQuantumProcessorAccessorsResponse",
164 }),
165 }
166 } else {
167 let local_var_retry_delay =
168 duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
169 let local_var_content = local_var_resp.text().await?;
170 let local_var_entity: Option<GetEndpointAccessorsError> =
171 serde_json::from_str(&local_var_content).ok();
172 let local_var_error = ResponseContent {
173 status: local_var_status,
174 content: local_var_content,
175 entity: local_var_entity,
176 retry_delay: local_var_retry_delay,
177 };
178 Err(Error::ResponseError(local_var_error))
179 }
180}
181
182pub async fn get_endpoint_accessors(
183 configuration: &configuration::Configuration,
184 endpoint_id: &str,
185) -> Result<models::ListQuantumProcessorAccessorsResponse, Error<GetEndpointAccessorsError>> {
186 let mut backoff = configuration.backoff.build();
187 let mut refreshed_credentials = false;
188 let method = reqwest::Method::GET;
189 loop {
190 let result =
191 get_endpoint_accessors_inner(configuration, &mut backoff, endpoint_id.clone()).await;
192
193 match result {
194 Ok(result) => return Ok(result),
195 Err(Error::ResponseError(response)) => {
196 if !refreshed_credentials
197 && matches!(
198 response.status,
199 StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
200 )
201 {
202 match configuration.qcs_config.refresh().await {
204 Ok(_) => {
205 refreshed_credentials = true;
206 continue;
207 }
208 Err(::qcs_api_client_common::configuration::TokenError::Write {
209 error,
210 oauth_session: _,
211 }) => {
212 #[cfg(feature = "tracing")]
215 tracing::warn!(
216 "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
217 error
218 );
219 refreshed_credentials = true;
220 continue;
221 }
222 Err(e) => return Err(e.into()),
223 }
224 } else if let Some(duration) = response.retry_delay {
225 tokio::time::sleep(duration).await;
226 continue;
227 }
228
229 return Err(Error::ResponseError(response));
230 }
231 Err(Error::Reqwest(error)) => {
232 if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
233 tokio::time::sleep(duration).await;
234 continue;
235 }
236
237 return Err(Error::Reqwest(error));
238 }
239 Err(Error::Io(error)) => {
240 if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
241 tokio::time::sleep(duration).await;
242 continue;
243 }
244
245 return Err(Error::Io(error));
246 }
247 Err(error) => return Err(error),
248 }
249 }
250}