Skip to main content

qcs_api_client_openapi/apis/
quantum_processors_api.rs

1// Copyright 2026 Rigetti Computing
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*
16 * Rigetti QCS API
17 *
18 * # Introduction  This is the documentation for the Rigetti QCS HTTP API.  You can find out more about Rigetti at [https://rigetti.com](https://rigetti.com), and also interact with QCS via the web at [https://qcs.rigetti.com](https://qcs.rigetti.com).  This API is documented in **OpenAPI format** and so is compatible with the dozens of language-specific client generators available [here](https://github.com/OpenAPITools/openapi-generator) and elsewhere on the web.  # Principles  This API follows REST design principles where appropriate, and otherwise an HTTP RPC paradigm. We adhere to the Google [API Improvement Proposals](https://google.aip.dev/general) where reasonable to provide a consistent, intuitive developer experience. HTTP response codes match their specifications, and error messages fit a common format.  # Authentication  All access to the QCS API requires OAuth2 authentication provided by Okta. You can request access [here](https://www.rigetti.com/get-quantum). Once you have a user account, you can download your access token from QCS [here](https://qcs.rigetti.com/auth/token).   That access token is valid for 24 hours after issuance. The value of `access_token` within the JSON file is the token used for authentication (don't use the entire JSON file).  Authenticate requests using the `Authorization` header and a `Bearer` prefix:  ``` curl --header \"Authorization: Bearer eyJraW...Iow\" ```  # Quantum Processor Access  Access to the quantum processors themselves is not yet provided directly by this HTTP API, but is instead performed over ZeroMQ/[rpcq](https://github.com/rigetti/rpcq). Until that changes, we suggest using [pyquil](https://github.com/rigetti/pyquil) to build and execute quantum programs via the Legacy API.  # Legacy API  Our legacy HTTP API remains accessible at https://forest-server.qcs.rigetti.com, and it shares a source of truth with this API's services. You can use either service with the same user account and means of authentication. We strongly recommend using the API documented here, as the legacy API is on the path to deprecation.
19 *
20 * The version of the OpenAPI document: 2020-07-31
21 * Contact: support@rigetti.com
22 * Generated by: https://openapi-generator.tech
23 */
24
25use super::{ContentType, Error, configuration};
26use crate::{apis::ResponseContent, models};
27use ::qcs_api_client_common::backoff::{
28    ExponentialBackoff, duration_from_io_error, duration_from_reqwest_error, duration_from_response,
29};
30#[cfg(feature = "tracing")]
31use qcs_api_client_common::configuration::tokens::TokenRefresher;
32use qcs_dependencies_client::reqwest::{self, StatusCode};
33use serde::{Deserialize, Serialize};
34
35#[cfg(feature = "clap")]
36#[allow(unused, reason = "not used in all templates, but required in some")]
37use ::{miette::IntoDiagnostic as _, qcs_api_client_common::clap_utils::JsonMaybeStdin};
38
39/// Serialize command-line arguments for [`get_instruction_set_architecture`]
40#[cfg(feature = "clap")]
41#[derive(Debug, clap::Args)]
42pub struct GetInstructionSetArchitectureClapParams {
43    #[arg(long)]
44    pub quantum_processor_id: String,
45}
46
47#[cfg(feature = "clap")]
48impl GetInstructionSetArchitectureClapParams {
49    pub async fn execute(
50        self,
51        configuration: &configuration::Configuration,
52    ) -> Result<models::InstructionSetArchitecture, miette::Error> {
53        get_instruction_set_architecture(configuration, self.quantum_processor_id.as_str())
54            .await
55            .into_diagnostic()
56    }
57}
58
59/// Serialize command-line arguments for [`get_quantum_processor`]
60#[cfg(feature = "clap")]
61#[derive(Debug, clap::Args)]
62pub struct GetQuantumProcessorClapParams {
63    #[arg(long)]
64    pub quantum_processor_id: String,
65}
66
67#[cfg(feature = "clap")]
68impl GetQuantumProcessorClapParams {
69    pub async fn execute(
70        self,
71        configuration: &configuration::Configuration,
72    ) -> Result<models::QuantumProcessor, miette::Error> {
73        get_quantum_processor(configuration, self.quantum_processor_id.as_str())
74            .await
75            .into_diagnostic()
76    }
77}
78
79/// Serialize command-line arguments for [`get_quantum_processor_accessors`]
80#[cfg(feature = "clap")]
81#[derive(Debug, clap::Args)]
82pub struct GetQuantumProcessorAccessorsClapParams {
83    #[arg(long)]
84    pub quantum_processor_id: String,
85}
86
87#[cfg(feature = "clap")]
88impl GetQuantumProcessorAccessorsClapParams {
89    pub async fn execute(
90        self,
91        configuration: &configuration::Configuration,
92    ) -> Result<models::ListQuantumProcessorAccessorsResponse, miette::Error> {
93        get_quantum_processor_accessors(configuration, self.quantum_processor_id.as_str())
94            .await
95            .into_diagnostic()
96    }
97}
98
99/// Serialize command-line arguments for [`list_instruction_set_architectures`]
100#[cfg(feature = "clap")]
101#[derive(Debug, clap::Args)]
102pub struct ListInstructionSetArchitecturesClapParams {
103    #[arg(long)]
104    pub page_size: Option<u64>,
105    #[arg(long)]
106    pub page_token: Option<String>,
107}
108
109#[cfg(feature = "clap")]
110impl ListInstructionSetArchitecturesClapParams {
111    pub async fn execute(
112        self,
113        configuration: &configuration::Configuration,
114    ) -> Result<models::ListInstructionSetArchitectureResponse, miette::Error> {
115        list_instruction_set_architectures(
116            configuration,
117            self.page_size,
118            self.page_token.as_deref(),
119        )
120        .await
121        .into_diagnostic()
122    }
123}
124
125/// Serialize command-line arguments for [`list_quantum_processors`]
126#[cfg(feature = "clap")]
127#[derive(Debug, clap::Args)]
128pub struct ListQuantumProcessorsClapParams {
129    #[arg(long)]
130    pub page_size: Option<u64>,
131    #[arg(long)]
132    pub page_token: Option<String>,
133}
134
135#[cfg(feature = "clap")]
136impl ListQuantumProcessorsClapParams {
137    pub async fn execute(
138        self,
139        configuration: &configuration::Configuration,
140    ) -> Result<models::ListQuantumProcessorsResponse, miette::Error> {
141        list_quantum_processors(configuration, self.page_size, self.page_token.as_deref())
142            .await
143            .into_diagnostic()
144    }
145}
146
147/// struct for typed errors of method [`get_instruction_set_architecture`]
148#[derive(Debug, Clone, Serialize, Deserialize)]
149#[serde(untagged)]
150pub enum GetInstructionSetArchitectureError {
151    Status422(models::ValidationError),
152    DefaultResponse(models::Error),
153    UnknownValue(serde_json::Value),
154}
155
156/// struct for typed errors of method [`get_quantum_processor`]
157#[derive(Debug, Clone, Serialize, Deserialize)]
158#[serde(untagged)]
159pub enum GetQuantumProcessorError {
160    Status422(models::ValidationError),
161    DefaultResponse(models::Error),
162    UnknownValue(serde_json::Value),
163}
164
165/// struct for typed errors of method [`get_quantum_processor_accessors`]
166#[derive(Debug, Clone, Serialize, Deserialize)]
167#[serde(untagged)]
168pub enum GetQuantumProcessorAccessorsError {
169    Status422(models::ValidationError),
170    DefaultResponse(models::Error),
171    UnknownValue(serde_json::Value),
172}
173
174/// struct for typed errors of method [`list_instruction_set_architectures`]
175#[derive(Debug, Clone, Serialize, Deserialize)]
176#[serde(untagged)]
177pub enum ListInstructionSetArchitecturesError {
178    Status422(models::ValidationError),
179    DefaultResponse(models::Error),
180    UnknownValue(serde_json::Value),
181}
182
183/// struct for typed errors of method [`list_quantum_processors`]
184#[derive(Debug, Clone, Serialize, Deserialize)]
185#[serde(untagged)]
186pub enum ListQuantumProcessorsError {
187    Status422(models::ValidationError),
188    DefaultResponse(models::Error),
189    UnknownValue(serde_json::Value),
190}
191
192async fn get_instruction_set_architecture_inner(
193    configuration: &configuration::Configuration,
194    backoff: &mut ExponentialBackoff,
195    quantum_processor_id: &str,
196) -> Result<models::InstructionSetArchitecture, Error<GetInstructionSetArchitectureError>> {
197    let local_var_configuration = configuration;
198    // add a prefix to parameters to efficiently prevent name collisions
199    let p_path_quantum_processor_id = quantum_processor_id;
200
201    let local_var_client = &local_var_configuration.client;
202
203    let local_var_uri_str = format!(
204        "{}/v1/quantumProcessors/{quantum_processor_id}/instructionSetArchitecture",
205        local_var_configuration.qcs_config.api_url(),
206        quantum_processor_id = crate::apis::urlencode(p_path_quantum_processor_id)
207    );
208    let mut local_var_req_builder =
209        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
210
211    #[cfg(feature = "tracing")]
212    {
213        // Ignore parsing errors if the URL is invalid for some reason.
214        // If it is invalid, it will turn up as an error later when actually making the request.
215        let local_var_do_tracing = local_var_uri_str
216            .parse::<::url::Url>()
217            .ok()
218            .is_none_or(|url| {
219                configuration
220                    .qcs_config
221                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
222            });
223
224        if local_var_do_tracing {
225            ::tracing::debug!(
226                url=%local_var_uri_str,
227                method="GET",
228                "making get_instruction_set_architecture request",
229            );
230        }
231    }
232
233    // Use the QCS Bearer token if a client OAuthSession is present,
234    // but do not require one when the security schema says it is optional.
235    {
236        use qcs_api_client_common::configuration::TokenError;
237
238        #[allow(
239            clippy::nonminimal_bool,
240            clippy::eq_op,
241            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
242        )]
243        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
244
245        let token = local_var_configuration
246            .qcs_config
247            .get_bearer_access_token()
248            .await;
249
250        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
251            // the client is configured without any OAuthSession, but this call does not require one.
252            #[cfg(feature = "tracing")]
253            tracing::debug!(
254                "No client credentials found, but this call does not require authentication."
255            );
256        } else {
257            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
258        }
259    }
260
261    let local_var_req = local_var_req_builder.build()?;
262    let local_var_resp = local_var_client.execute(local_var_req).await?;
263
264    let local_var_status = local_var_resp.status();
265    let local_var_raw_content_type = local_var_resp
266        .headers()
267        .get("content-type")
268        .and_then(|v| v.to_str().ok())
269        .unwrap_or("application/octet-stream")
270        .to_string();
271    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
272
273    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
274        let local_var_content = local_var_resp.text().await?;
275        match local_var_content_type {
276            ContentType::Json => serde_path_to_error::deserialize(
277                &mut serde_json::Deserializer::from_str(&local_var_content),
278            )
279            .map_err(Error::from),
280            ContentType::Text => Err(Error::InvalidContentType {
281                content_type: local_var_raw_content_type,
282                return_type: "models::InstructionSetArchitecture",
283            }),
284            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
285                content_type: unknown_type,
286                return_type: "models::InstructionSetArchitecture",
287            }),
288        }
289    } else {
290        let local_var_retry_delay =
291            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
292        let local_var_content = local_var_resp.text().await?;
293        let local_var_entity: Option<GetInstructionSetArchitectureError> =
294            serde_json::from_str(&local_var_content).ok();
295        let local_var_error = ResponseContent {
296            status: local_var_status,
297            content: local_var_content,
298            entity: local_var_entity,
299            retry_delay: local_var_retry_delay,
300        };
301        Err(Error::ResponseError(local_var_error))
302    }
303}
304
305pub async fn get_instruction_set_architecture(
306    configuration: &configuration::Configuration,
307    quantum_processor_id: &str,
308) -> Result<models::InstructionSetArchitecture, Error<GetInstructionSetArchitectureError>> {
309    let mut backoff = configuration.backoff.clone();
310    let mut refreshed_credentials = false;
311    let method = reqwest::Method::GET;
312    loop {
313        let result = get_instruction_set_architecture_inner(
314            configuration,
315            &mut backoff,
316            quantum_processor_id.clone(),
317        )
318        .await;
319
320        match result {
321            Ok(result) => return Ok(result),
322            Err(Error::ResponseError(response)) => {
323                if !refreshed_credentials
324                    && matches!(
325                        response.status,
326                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
327                    )
328                {
329                    // Attempt to refresh credentials
330                    match configuration.qcs_config.refresh().await {
331                        Ok(_) => {
332                            refreshed_credentials = true;
333                            continue;
334                        }
335                        Err(::qcs_api_client_common::configuration::TokenError::Write {
336                            error,
337                            oauth_session: _,
338                        }) => {
339                            // Token refresh succeeded but persistence failed
340                            // The token is already in memory and will be used for this request
341                            #[cfg(feature = "tracing")]
342                            tracing::warn!(
343                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
344                                error
345                            );
346                            refreshed_credentials = true;
347                            continue;
348                        }
349                        Err(e) => return Err(e.into()),
350                    }
351                } else if let Some(duration) = response.retry_delay {
352                    tokio::time::sleep(duration).await;
353                    continue;
354                }
355
356                return Err(Error::ResponseError(response));
357            }
358            Err(Error::Reqwest(error)) => {
359                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
360                    tokio::time::sleep(duration).await;
361                    continue;
362                }
363
364                return Err(Error::Reqwest(error));
365            }
366            Err(Error::Io(error)) => {
367                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
368                    tokio::time::sleep(duration).await;
369                    continue;
370                }
371
372                return Err(Error::Io(error));
373            }
374            Err(error) => return Err(error),
375        }
376    }
377}
378async fn get_quantum_processor_inner(
379    configuration: &configuration::Configuration,
380    backoff: &mut ExponentialBackoff,
381    quantum_processor_id: &str,
382) -> Result<models::QuantumProcessor, Error<GetQuantumProcessorError>> {
383    let local_var_configuration = configuration;
384    // add a prefix to parameters to efficiently prevent name collisions
385    let p_path_quantum_processor_id = quantum_processor_id;
386
387    let local_var_client = &local_var_configuration.client;
388
389    let local_var_uri_str = format!(
390        "{}/v1/quantumProcessors/{quantum_processor_id}",
391        local_var_configuration.qcs_config.api_url(),
392        quantum_processor_id = crate::apis::urlencode(p_path_quantum_processor_id)
393    );
394    let mut local_var_req_builder =
395        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
396
397    #[cfg(feature = "tracing")]
398    {
399        // Ignore parsing errors if the URL is invalid for some reason.
400        // If it is invalid, it will turn up as an error later when actually making the request.
401        let local_var_do_tracing = local_var_uri_str
402            .parse::<::url::Url>()
403            .ok()
404            .is_none_or(|url| {
405                configuration
406                    .qcs_config
407                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
408            });
409
410        if local_var_do_tracing {
411            ::tracing::debug!(
412                url=%local_var_uri_str,
413                method="GET",
414                "making get_quantum_processor request",
415            );
416        }
417    }
418
419    // Use the QCS Bearer token if a client OAuthSession is present,
420    // but do not require one when the security schema says it is optional.
421    {
422        use qcs_api_client_common::configuration::TokenError;
423
424        #[allow(
425            clippy::nonminimal_bool,
426            clippy::eq_op,
427            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
428        )]
429        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
430
431        let token = local_var_configuration
432            .qcs_config
433            .get_bearer_access_token()
434            .await;
435
436        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
437            // the client is configured without any OAuthSession, but this call does not require one.
438            #[cfg(feature = "tracing")]
439            tracing::debug!(
440                "No client credentials found, but this call does not require authentication."
441            );
442        } else {
443            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
444        }
445    }
446
447    let local_var_req = local_var_req_builder.build()?;
448    let local_var_resp = local_var_client.execute(local_var_req).await?;
449
450    let local_var_status = local_var_resp.status();
451    let local_var_raw_content_type = local_var_resp
452        .headers()
453        .get("content-type")
454        .and_then(|v| v.to_str().ok())
455        .unwrap_or("application/octet-stream")
456        .to_string();
457    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
458
459    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
460        let local_var_content = local_var_resp.text().await?;
461        match local_var_content_type {
462            ContentType::Json => serde_path_to_error::deserialize(
463                &mut serde_json::Deserializer::from_str(&local_var_content),
464            )
465            .map_err(Error::from),
466            ContentType::Text => Err(Error::InvalidContentType {
467                content_type: local_var_raw_content_type,
468                return_type: "models::QuantumProcessor",
469            }),
470            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
471                content_type: unknown_type,
472                return_type: "models::QuantumProcessor",
473            }),
474        }
475    } else {
476        let local_var_retry_delay =
477            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
478        let local_var_content = local_var_resp.text().await?;
479        let local_var_entity: Option<GetQuantumProcessorError> =
480            serde_json::from_str(&local_var_content).ok();
481        let local_var_error = ResponseContent {
482            status: local_var_status,
483            content: local_var_content,
484            entity: local_var_entity,
485            retry_delay: local_var_retry_delay,
486        };
487        Err(Error::ResponseError(local_var_error))
488    }
489}
490
491/// Retrieve a single `QuantumProcessor` by ID.
492pub async fn get_quantum_processor(
493    configuration: &configuration::Configuration,
494    quantum_processor_id: &str,
495) -> Result<models::QuantumProcessor, Error<GetQuantumProcessorError>> {
496    let mut backoff = configuration.backoff.clone();
497    let mut refreshed_credentials = false;
498    let method = reqwest::Method::GET;
499    loop {
500        let result =
501            get_quantum_processor_inner(configuration, &mut backoff, quantum_processor_id.clone())
502                .await;
503
504        match result {
505            Ok(result) => return Ok(result),
506            Err(Error::ResponseError(response)) => {
507                if !refreshed_credentials
508                    && matches!(
509                        response.status,
510                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
511                    )
512                {
513                    // Attempt to refresh credentials
514                    match configuration.qcs_config.refresh().await {
515                        Ok(_) => {
516                            refreshed_credentials = true;
517                            continue;
518                        }
519                        Err(::qcs_api_client_common::configuration::TokenError::Write {
520                            error,
521                            oauth_session: _,
522                        }) => {
523                            // Token refresh succeeded but persistence failed
524                            // The token is already in memory and will be used for this request
525                            #[cfg(feature = "tracing")]
526                            tracing::warn!(
527                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
528                                error
529                            );
530                            refreshed_credentials = true;
531                            continue;
532                        }
533                        Err(e) => return Err(e.into()),
534                    }
535                } else if let Some(duration) = response.retry_delay {
536                    tokio::time::sleep(duration).await;
537                    continue;
538                }
539
540                return Err(Error::ResponseError(response));
541            }
542            Err(Error::Reqwest(error)) => {
543                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
544                    tokio::time::sleep(duration).await;
545                    continue;
546                }
547
548                return Err(Error::Reqwest(error));
549            }
550            Err(Error::Io(error)) => {
551                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
552                    tokio::time::sleep(duration).await;
553                    continue;
554                }
555
556                return Err(Error::Io(error));
557            }
558            Err(error) => return Err(error),
559        }
560    }
561}
562async fn get_quantum_processor_accessors_inner(
563    configuration: &configuration::Configuration,
564    backoff: &mut ExponentialBackoff,
565    quantum_processor_id: &str,
566) -> Result<models::ListQuantumProcessorAccessorsResponse, Error<GetQuantumProcessorAccessorsError>>
567{
568    let local_var_configuration = configuration;
569    // add a prefix to parameters to efficiently prevent name collisions
570    let p_path_quantum_processor_id = quantum_processor_id;
571
572    let local_var_client = &local_var_configuration.client;
573
574    let local_var_uri_str = format!(
575        "{}/v1/quantumProcessors/{quantum_processor_id}/accessors",
576        local_var_configuration.qcs_config.api_url(),
577        quantum_processor_id = crate::apis::urlencode(p_path_quantum_processor_id)
578    );
579    let mut local_var_req_builder =
580        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
581
582    #[cfg(feature = "tracing")]
583    {
584        // Ignore parsing errors if the URL is invalid for some reason.
585        // If it is invalid, it will turn up as an error later when actually making the request.
586        let local_var_do_tracing = local_var_uri_str
587            .parse::<::url::Url>()
588            .ok()
589            .is_none_or(|url| {
590                configuration
591                    .qcs_config
592                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
593            });
594
595        if local_var_do_tracing {
596            ::tracing::debug!(
597                url=%local_var_uri_str,
598                method="GET",
599                "making get_quantum_processor_accessors request",
600            );
601        }
602    }
603
604    // Use the QCS Bearer token if a client OAuthSession is present,
605    // but do not require one when the security schema says it is optional.
606    {
607        use qcs_api_client_common::configuration::TokenError;
608
609        #[allow(
610            clippy::nonminimal_bool,
611            clippy::eq_op,
612            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
613        )]
614        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
615
616        let token = local_var_configuration
617            .qcs_config
618            .get_bearer_access_token()
619            .await;
620
621        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
622            // the client is configured without any OAuthSession, but this call does not require one.
623            #[cfg(feature = "tracing")]
624            tracing::debug!(
625                "No client credentials found, but this call does not require authentication."
626            );
627        } else {
628            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
629        }
630    }
631
632    let local_var_req = local_var_req_builder.build()?;
633    let local_var_resp = local_var_client.execute(local_var_req).await?;
634
635    let local_var_status = local_var_resp.status();
636    let local_var_raw_content_type = local_var_resp
637        .headers()
638        .get("content-type")
639        .and_then(|v| v.to_str().ok())
640        .unwrap_or("application/octet-stream")
641        .to_string();
642    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
643
644    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
645        let local_var_content = local_var_resp.text().await?;
646        match local_var_content_type {
647            ContentType::Json => serde_path_to_error::deserialize(
648                &mut serde_json::Deserializer::from_str(&local_var_content),
649            )
650            .map_err(Error::from),
651            ContentType::Text => Err(Error::InvalidContentType {
652                content_type: local_var_raw_content_type,
653                return_type: "models::ListQuantumProcessorAccessorsResponse",
654            }),
655            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
656                content_type: unknown_type,
657                return_type: "models::ListQuantumProcessorAccessorsResponse",
658            }),
659        }
660    } else {
661        let local_var_retry_delay =
662            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
663        let local_var_content = local_var_resp.text().await?;
664        let local_var_entity: Option<GetQuantumProcessorAccessorsError> =
665            serde_json::from_str(&local_var_content).ok();
666        let local_var_error = ResponseContent {
667            status: local_var_status,
668            content: local_var_content,
669            entity: local_var_entity,
670            retry_delay: local_var_retry_delay,
671        };
672        Err(Error::ResponseError(local_var_error))
673    }
674}
675
676/// Retrieve a single `QuantumProcessor` by ID.
677pub async fn get_quantum_processor_accessors(
678    configuration: &configuration::Configuration,
679    quantum_processor_id: &str,
680) -> Result<models::ListQuantumProcessorAccessorsResponse, Error<GetQuantumProcessorAccessorsError>>
681{
682    let mut backoff = configuration.backoff.clone();
683    let mut refreshed_credentials = false;
684    let method = reqwest::Method::GET;
685    loop {
686        let result = get_quantum_processor_accessors_inner(
687            configuration,
688            &mut backoff,
689            quantum_processor_id.clone(),
690        )
691        .await;
692
693        match result {
694            Ok(result) => return Ok(result),
695            Err(Error::ResponseError(response)) => {
696                if !refreshed_credentials
697                    && matches!(
698                        response.status,
699                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
700                    )
701                {
702                    // Attempt to refresh credentials
703                    match configuration.qcs_config.refresh().await {
704                        Ok(_) => {
705                            refreshed_credentials = true;
706                            continue;
707                        }
708                        Err(::qcs_api_client_common::configuration::TokenError::Write {
709                            error,
710                            oauth_session: _,
711                        }) => {
712                            // Token refresh succeeded but persistence failed
713                            // The token is already in memory and will be used for this request
714                            #[cfg(feature = "tracing")]
715                            tracing::warn!(
716                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
717                                error
718                            );
719                            refreshed_credentials = true;
720                            continue;
721                        }
722                        Err(e) => return Err(e.into()),
723                    }
724                } else if let Some(duration) = response.retry_delay {
725                    tokio::time::sleep(duration).await;
726                    continue;
727                }
728
729                return Err(Error::ResponseError(response));
730            }
731            Err(Error::Reqwest(error)) => {
732                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
733                    tokio::time::sleep(duration).await;
734                    continue;
735                }
736
737                return Err(Error::Reqwest(error));
738            }
739            Err(Error::Io(error)) => {
740                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
741                    tokio::time::sleep(duration).await;
742                    continue;
743                }
744
745                return Err(Error::Io(error));
746            }
747            Err(error) => return Err(error),
748        }
749    }
750}
751async fn list_instruction_set_architectures_inner(
752    configuration: &configuration::Configuration,
753    backoff: &mut ExponentialBackoff,
754    page_size: Option<u64>,
755    page_token: Option<&str>,
756) -> Result<
757    models::ListInstructionSetArchitectureResponse,
758    Error<ListInstructionSetArchitecturesError>,
759> {
760    let local_var_configuration = configuration;
761    // add a prefix to parameters to efficiently prevent name collisions
762    let p_query_page_size = page_size;
763    let p_query_page_token = page_token;
764
765    let local_var_client = &local_var_configuration.client;
766
767    let local_var_uri_str = format!(
768        "{}/v1/instructionSetArchitectures",
769        local_var_configuration.qcs_config.api_url()
770    );
771    let mut local_var_req_builder =
772        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
773
774    #[cfg(feature = "tracing")]
775    {
776        // Ignore parsing errors if the URL is invalid for some reason.
777        // If it is invalid, it will turn up as an error later when actually making the request.
778        let local_var_do_tracing = local_var_uri_str
779            .parse::<::url::Url>()
780            .ok()
781            .is_none_or(|url| {
782                configuration
783                    .qcs_config
784                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
785            });
786
787        if local_var_do_tracing {
788            ::tracing::debug!(
789                url=%local_var_uri_str,
790                method="GET",
791                "making list_instruction_set_architectures request",
792            );
793        }
794    }
795
796    if let Some(ref local_var_str) = p_query_page_size {
797        local_var_req_builder =
798            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
799    }
800    if let Some(ref local_var_str) = p_query_page_token {
801        local_var_req_builder =
802            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
803    }
804
805    // Use the QCS Bearer token if a client OAuthSession is present,
806    // but do not require one when the security schema says it is optional.
807    {
808        use qcs_api_client_common::configuration::TokenError;
809
810        #[allow(
811            clippy::nonminimal_bool,
812            clippy::eq_op,
813            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
814        )]
815        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
816
817        let token = local_var_configuration
818            .qcs_config
819            .get_bearer_access_token()
820            .await;
821
822        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
823            // the client is configured without any OAuthSession, but this call does not require one.
824            #[cfg(feature = "tracing")]
825            tracing::debug!(
826                "No client credentials found, but this call does not require authentication."
827            );
828        } else {
829            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
830        }
831    }
832
833    let local_var_req = local_var_req_builder.build()?;
834    let local_var_resp = local_var_client.execute(local_var_req).await?;
835
836    let local_var_status = local_var_resp.status();
837    let local_var_raw_content_type = local_var_resp
838        .headers()
839        .get("content-type")
840        .and_then(|v| v.to_str().ok())
841        .unwrap_or("application/octet-stream")
842        .to_string();
843    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
844
845    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
846        let local_var_content = local_var_resp.text().await?;
847        match local_var_content_type {
848            ContentType::Json => serde_path_to_error::deserialize(
849                &mut serde_json::Deserializer::from_str(&local_var_content),
850            )
851            .map_err(Error::from),
852            ContentType::Text => Err(Error::InvalidContentType {
853                content_type: local_var_raw_content_type,
854                return_type: "models::ListInstructionSetArchitectureResponse",
855            }),
856            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
857                content_type: unknown_type,
858                return_type: "models::ListInstructionSetArchitectureResponse",
859            }),
860        }
861    } else {
862        let local_var_retry_delay =
863            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
864        let local_var_content = local_var_resp.text().await?;
865        let local_var_entity: Option<ListInstructionSetArchitecturesError> =
866            serde_json::from_str(&local_var_content).ok();
867        let local_var_error = ResponseContent {
868            status: local_var_status,
869            content: local_var_content,
870            entity: local_var_entity,
871            retry_delay: local_var_retry_delay,
872        };
873        Err(Error::ResponseError(local_var_error))
874    }
875}
876
877pub async fn list_instruction_set_architectures(
878    configuration: &configuration::Configuration,
879    page_size: Option<u64>,
880    page_token: Option<&str>,
881) -> Result<
882    models::ListInstructionSetArchitectureResponse,
883    Error<ListInstructionSetArchitecturesError>,
884> {
885    let mut backoff = configuration.backoff.clone();
886    let mut refreshed_credentials = false;
887    let method = reqwest::Method::GET;
888    loop {
889        let result = list_instruction_set_architectures_inner(
890            configuration,
891            &mut backoff,
892            page_size.clone(),
893            page_token.clone(),
894        )
895        .await;
896
897        match result {
898            Ok(result) => return Ok(result),
899            Err(Error::ResponseError(response)) => {
900                if !refreshed_credentials
901                    && matches!(
902                        response.status,
903                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
904                    )
905                {
906                    // Attempt to refresh credentials
907                    match configuration.qcs_config.refresh().await {
908                        Ok(_) => {
909                            refreshed_credentials = true;
910                            continue;
911                        }
912                        Err(::qcs_api_client_common::configuration::TokenError::Write {
913                            error,
914                            oauth_session: _,
915                        }) => {
916                            // Token refresh succeeded but persistence failed
917                            // The token is already in memory and will be used for this request
918                            #[cfg(feature = "tracing")]
919                            tracing::warn!(
920                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
921                                error
922                            );
923                            refreshed_credentials = true;
924                            continue;
925                        }
926                        Err(e) => return Err(e.into()),
927                    }
928                } else if let Some(duration) = response.retry_delay {
929                    tokio::time::sleep(duration).await;
930                    continue;
931                }
932
933                return Err(Error::ResponseError(response));
934            }
935            Err(Error::Reqwest(error)) => {
936                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
937                    tokio::time::sleep(duration).await;
938                    continue;
939                }
940
941                return Err(Error::Reqwest(error));
942            }
943            Err(Error::Io(error)) => {
944                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
945                    tokio::time::sleep(duration).await;
946                    continue;
947                }
948
949                return Err(Error::Io(error));
950            }
951            Err(error) => return Err(error),
952        }
953    }
954}
955async fn list_quantum_processors_inner(
956    configuration: &configuration::Configuration,
957    backoff: &mut ExponentialBackoff,
958    page_size: Option<u64>,
959    page_token: Option<&str>,
960) -> Result<models::ListQuantumProcessorsResponse, Error<ListQuantumProcessorsError>> {
961    let local_var_configuration = configuration;
962    // add a prefix to parameters to efficiently prevent name collisions
963    let p_query_page_size = page_size;
964    let p_query_page_token = page_token;
965
966    let local_var_client = &local_var_configuration.client;
967
968    let local_var_uri_str = format!(
969        "{}/v1/quantumProcessors",
970        local_var_configuration.qcs_config.api_url()
971    );
972    let mut local_var_req_builder =
973        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
974
975    #[cfg(feature = "tracing")]
976    {
977        // Ignore parsing errors if the URL is invalid for some reason.
978        // If it is invalid, it will turn up as an error later when actually making the request.
979        let local_var_do_tracing = local_var_uri_str
980            .parse::<::url::Url>()
981            .ok()
982            .is_none_or(|url| {
983                configuration
984                    .qcs_config
985                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
986            });
987
988        if local_var_do_tracing {
989            ::tracing::debug!(
990                url=%local_var_uri_str,
991                method="GET",
992                "making list_quantum_processors request",
993            );
994        }
995    }
996
997    if let Some(ref local_var_str) = p_query_page_size {
998        local_var_req_builder =
999            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
1000    }
1001    if let Some(ref local_var_str) = p_query_page_token {
1002        local_var_req_builder =
1003            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
1004    }
1005
1006    // Use the QCS Bearer token if a client OAuthSession is present,
1007    // but do not require one when the security schema says it is optional.
1008    {
1009        use qcs_api_client_common::configuration::TokenError;
1010
1011        #[allow(
1012            clippy::nonminimal_bool,
1013            clippy::eq_op,
1014            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1015        )]
1016        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
1017
1018        let token = local_var_configuration
1019            .qcs_config
1020            .get_bearer_access_token()
1021            .await;
1022
1023        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1024            // the client is configured without any OAuthSession, but this call does not require one.
1025            #[cfg(feature = "tracing")]
1026            tracing::debug!(
1027                "No client credentials found, but this call does not require authentication."
1028            );
1029        } else {
1030            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1031        }
1032    }
1033
1034    let local_var_req = local_var_req_builder.build()?;
1035    let local_var_resp = local_var_client.execute(local_var_req).await?;
1036
1037    let local_var_status = local_var_resp.status();
1038    let local_var_raw_content_type = local_var_resp
1039        .headers()
1040        .get("content-type")
1041        .and_then(|v| v.to_str().ok())
1042        .unwrap_or("application/octet-stream")
1043        .to_string();
1044    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
1045
1046    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1047        let local_var_content = local_var_resp.text().await?;
1048        match local_var_content_type {
1049            ContentType::Json => serde_path_to_error::deserialize(
1050                &mut serde_json::Deserializer::from_str(&local_var_content),
1051            )
1052            .map_err(Error::from),
1053            ContentType::Text => Err(Error::InvalidContentType {
1054                content_type: local_var_raw_content_type,
1055                return_type: "models::ListQuantumProcessorsResponse",
1056            }),
1057            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
1058                content_type: unknown_type,
1059                return_type: "models::ListQuantumProcessorsResponse",
1060            }),
1061        }
1062    } else {
1063        let local_var_retry_delay =
1064            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1065        let local_var_content = local_var_resp.text().await?;
1066        let local_var_entity: Option<ListQuantumProcessorsError> =
1067            serde_json::from_str(&local_var_content).ok();
1068        let local_var_error = ResponseContent {
1069            status: local_var_status,
1070            content: local_var_content,
1071            entity: local_var_entity,
1072            retry_delay: local_var_retry_delay,
1073        };
1074        Err(Error::ResponseError(local_var_error))
1075    }
1076}
1077
1078/// List the [`QuantumProcessor`]s that this user is authorized to access.  If no auth token is provided, only public processors will be returned.
1079pub async fn list_quantum_processors(
1080    configuration: &configuration::Configuration,
1081    page_size: Option<u64>,
1082    page_token: Option<&str>,
1083) -> Result<models::ListQuantumProcessorsResponse, Error<ListQuantumProcessorsError>> {
1084    let mut backoff = configuration.backoff.clone();
1085    let mut refreshed_credentials = false;
1086    let method = reqwest::Method::GET;
1087    loop {
1088        let result = list_quantum_processors_inner(
1089            configuration,
1090            &mut backoff,
1091            page_size.clone(),
1092            page_token.clone(),
1093        )
1094        .await;
1095
1096        match result {
1097            Ok(result) => return Ok(result),
1098            Err(Error::ResponseError(response)) => {
1099                if !refreshed_credentials
1100                    && matches!(
1101                        response.status,
1102                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1103                    )
1104                {
1105                    // Attempt to refresh credentials
1106                    match configuration.qcs_config.refresh().await {
1107                        Ok(_) => {
1108                            refreshed_credentials = true;
1109                            continue;
1110                        }
1111                        Err(::qcs_api_client_common::configuration::TokenError::Write {
1112                            error,
1113                            oauth_session: _,
1114                        }) => {
1115                            // Token refresh succeeded but persistence failed
1116                            // The token is already in memory and will be used for this request
1117                            #[cfg(feature = "tracing")]
1118                            tracing::warn!(
1119                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
1120                                error
1121                            );
1122                            refreshed_credentials = true;
1123                            continue;
1124                        }
1125                        Err(e) => return Err(e.into()),
1126                    }
1127                } else if let Some(duration) = response.retry_delay {
1128                    tokio::time::sleep(duration).await;
1129                    continue;
1130                }
1131
1132                return Err(Error::ResponseError(response));
1133            }
1134            Err(Error::Reqwest(error)) => {
1135                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1136                    tokio::time::sleep(duration).await;
1137                    continue;
1138                }
1139
1140                return Err(Error::Reqwest(error));
1141            }
1142            Err(Error::Io(error)) => {
1143                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1144                    tokio::time::sleep(duration).await;
1145                    continue;
1146                }
1147
1148                return Err(Error::Io(error));
1149            }
1150            Err(error) => return Err(error),
1151        }
1152    }
1153}