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