qcs_api_client_openapi/apis/
quantum_processors_api.rs

1// Copyright 2022 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::{configuration, Error};
26use crate::apis::ResponseContent;
27use ::qcs_api_client_common::backoff::{
28    duration_from_io_error, duration_from_reqwest_error, duration_from_response, ExponentialBackoff,
29};
30#[cfg(feature = "tracing")]
31use qcs_api_client_common::configuration::tokens::TokenRefresher;
32use reqwest::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<crate::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<crate::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 [`list_instruction_set_architectures`]
80#[cfg(feature = "clap")]
81#[derive(Debug, clap::Args)]
82pub struct ListInstructionSetArchitecturesClapParams {
83    #[arg(long)]
84    pub page_size: Option<i64>,
85    #[arg(long)]
86    pub page_token: Option<String>,
87}
88
89#[cfg(feature = "clap")]
90impl ListInstructionSetArchitecturesClapParams {
91    pub async fn execute(
92        self,
93        configuration: &configuration::Configuration,
94    ) -> Result<crate::models::ListInstructionSetArchitectureResponse, miette::Error> {
95        list_instruction_set_architectures(
96            configuration,
97            self.page_size,
98            self.page_token.as_deref(),
99        )
100        .await
101        .into_diagnostic()
102    }
103}
104
105/// Serialize command-line arguments for [`list_quantum_processor_accessors`]
106#[cfg(feature = "clap")]
107#[derive(Debug, clap::Args)]
108pub struct ListQuantumProcessorAccessorsClapParams {
109    /// Public identifier for a quantum processor [example: Aspen-1]
110    #[arg(long)]
111    pub quantum_processor_id: String,
112    #[arg(long)]
113    pub page_size: Option<i64>,
114    #[arg(long)]
115    pub page_token: Option<String>,
116}
117
118#[cfg(feature = "clap")]
119impl ListQuantumProcessorAccessorsClapParams {
120    pub async fn execute(
121        self,
122        configuration: &configuration::Configuration,
123    ) -> Result<crate::models::ListQuantumProcessorAccessorsResponse, miette::Error> {
124        list_quantum_processor_accessors(
125            configuration,
126            self.quantum_processor_id.as_str(),
127            self.page_size,
128            self.page_token.as_deref(),
129        )
130        .await
131        .into_diagnostic()
132    }
133}
134
135/// Serialize command-line arguments for [`list_quantum_processors`]
136#[cfg(feature = "clap")]
137#[derive(Debug, clap::Args)]
138pub struct ListQuantumProcessorsClapParams {
139    #[arg(long)]
140    pub page_size: Option<i64>,
141    #[arg(long)]
142    pub page_token: Option<String>,
143}
144
145#[cfg(feature = "clap")]
146impl ListQuantumProcessorsClapParams {
147    pub async fn execute(
148        self,
149        configuration: &configuration::Configuration,
150    ) -> Result<crate::models::ListQuantumProcessorsResponse, miette::Error> {
151        list_quantum_processors(configuration, self.page_size, self.page_token.as_deref())
152            .await
153            .into_diagnostic()
154    }
155}
156
157/// struct for typed errors of method [`get_instruction_set_architecture`]
158#[derive(Debug, Clone, Serialize, Deserialize)]
159#[serde(untagged)]
160pub enum GetInstructionSetArchitectureError {
161    Status422(crate::models::ValidationError),
162    DefaultResponse(crate::models::Error),
163    UnknownValue(serde_json::Value),
164}
165
166/// struct for typed errors of method [`get_quantum_processor`]
167#[derive(Debug, Clone, Serialize, Deserialize)]
168#[serde(untagged)]
169pub enum GetQuantumProcessorError {
170    Status422(crate::models::ValidationError),
171    DefaultResponse(crate::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(crate::models::ValidationError),
180    DefaultResponse(crate::models::Error),
181    UnknownValue(serde_json::Value),
182}
183
184/// struct for typed errors of method [`list_quantum_processor_accessors`]
185#[derive(Debug, Clone, Serialize, Deserialize)]
186#[serde(untagged)]
187pub enum ListQuantumProcessorAccessorsError {
188    Status422(crate::models::ValidationError),
189    UnknownValue(serde_json::Value),
190}
191
192/// struct for typed errors of method [`list_quantum_processors`]
193#[derive(Debug, Clone, Serialize, Deserialize)]
194#[serde(untagged)]
195pub enum ListQuantumProcessorsError {
196    Status422(crate::models::ValidationError),
197    DefaultResponse(crate::models::Error),
198    UnknownValue(serde_json::Value),
199}
200
201async fn get_instruction_set_architecture_inner(
202    configuration: &configuration::Configuration,
203    backoff: &mut ExponentialBackoff,
204    quantum_processor_id: &str,
205) -> Result<crate::models::InstructionSetArchitecture, Error<GetInstructionSetArchitectureError>> {
206    let local_var_configuration = configuration;
207
208    let local_var_client = &local_var_configuration.client;
209
210    let local_var_uri_str = format!(
211        "{}/v1/quantumProcessors/{quantum_processor_id}/instructionSetArchitecture",
212        local_var_configuration.qcs_config.api_url(),
213        quantum_processor_id = crate::apis::urlencode(quantum_processor_id)
214    );
215    let mut local_var_req_builder =
216        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
217
218    #[cfg(feature = "tracing")]
219    {
220        // Ignore parsing errors if the URL is invalid for some reason.
221        // If it is invalid, it will turn up as an error later when actually making the request.
222        let local_var_do_tracing = local_var_uri_str
223            .parse::<::url::Url>()
224            .ok()
225            .is_none_or(|url| {
226                configuration
227                    .qcs_config
228                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
229            });
230
231        if local_var_do_tracing {
232            ::tracing::debug!(
233                url=%local_var_uri_str,
234                method="GET",
235                "making get_instruction_set_architecture request",
236            );
237        }
238    }
239
240    // Use the QCS Bearer token if a client OAuthSession is present,
241    // but do not require one when the security schema says it is optional.
242    {
243        use qcs_api_client_common::configuration::TokenError;
244
245        #[allow(
246            clippy::nonminimal_bool,
247            clippy::eq_op,
248            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
249        )]
250        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
251
252        let token = local_var_configuration
253            .qcs_config
254            .get_bearer_access_token()
255            .await;
256
257        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
258            // the client is configured without any OAuthSession, but this call does not require one.
259            #[cfg(feature = "tracing")]
260            tracing::debug!(
261                "No client credentials found, but this call does not require authentication."
262            );
263        } else {
264            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
265        }
266    }
267
268    let local_var_req = local_var_req_builder.build()?;
269    let local_var_resp = local_var_client.execute(local_var_req).await?;
270
271    let local_var_status = local_var_resp.status();
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        serde_json::from_str(&local_var_content).map_err(Error::from)
276    } else {
277        let local_var_retry_delay =
278            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
279        let local_var_content = local_var_resp.text().await?;
280        let local_var_entity: Option<GetInstructionSetArchitectureError> =
281            serde_json::from_str(&local_var_content).ok();
282        let local_var_error = ResponseContent {
283            status: local_var_status,
284            content: local_var_content,
285            entity: local_var_entity,
286            retry_delay: local_var_retry_delay,
287        };
288        Err(Error::ResponseError(local_var_error))
289    }
290}
291
292pub async fn get_instruction_set_architecture(
293    configuration: &configuration::Configuration,
294    quantum_processor_id: &str,
295) -> Result<crate::models::InstructionSetArchitecture, Error<GetInstructionSetArchitectureError>> {
296    let mut backoff = configuration.backoff.clone();
297    let mut refreshed_credentials = false;
298    let method = reqwest::Method::GET;
299    loop {
300        let result = get_instruction_set_architecture_inner(
301            configuration,
302            &mut backoff,
303            quantum_processor_id.clone(),
304        )
305        .await;
306
307        match result {
308            Ok(result) => return Ok(result),
309            Err(Error::ResponseError(response)) => {
310                if !refreshed_credentials
311                    && matches!(
312                        response.status,
313                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
314                    )
315                {
316                    configuration.qcs_config.refresh().await?;
317                    refreshed_credentials = true;
318                    continue;
319                } else if let Some(duration) = response.retry_delay {
320                    tokio::time::sleep(duration).await;
321                    continue;
322                }
323
324                return Err(Error::ResponseError(response));
325            }
326            Err(Error::Reqwest(error)) => {
327                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
328                    tokio::time::sleep(duration).await;
329                    continue;
330                }
331
332                return Err(Error::Reqwest(error));
333            }
334            Err(Error::Io(error)) => {
335                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
336                    tokio::time::sleep(duration).await;
337                    continue;
338                }
339
340                return Err(Error::Io(error));
341            }
342            Err(error) => return Err(error),
343        }
344    }
345}
346async fn get_quantum_processor_inner(
347    configuration: &configuration::Configuration,
348    backoff: &mut ExponentialBackoff,
349    quantum_processor_id: &str,
350) -> Result<crate::models::QuantumProcessor, Error<GetQuantumProcessorError>> {
351    let local_var_configuration = configuration;
352
353    let local_var_client = &local_var_configuration.client;
354
355    let local_var_uri_str = format!(
356        "{}/v1/quantumProcessors/{quantum_processor_id}",
357        local_var_configuration.qcs_config.api_url(),
358        quantum_processor_id = crate::apis::urlencode(quantum_processor_id)
359    );
360    let mut local_var_req_builder =
361        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
362
363    #[cfg(feature = "tracing")]
364    {
365        // Ignore parsing errors if the URL is invalid for some reason.
366        // If it is invalid, it will turn up as an error later when actually making the request.
367        let local_var_do_tracing = local_var_uri_str
368            .parse::<::url::Url>()
369            .ok()
370            .is_none_or(|url| {
371                configuration
372                    .qcs_config
373                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
374            });
375
376        if local_var_do_tracing {
377            ::tracing::debug!(
378                url=%local_var_uri_str,
379                method="GET",
380                "making get_quantum_processor request",
381            );
382        }
383    }
384
385    // Use the QCS Bearer token if a client OAuthSession is present,
386    // but do not require one when the security schema says it is optional.
387    {
388        use qcs_api_client_common::configuration::TokenError;
389
390        #[allow(
391            clippy::nonminimal_bool,
392            clippy::eq_op,
393            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
394        )]
395        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
396
397        let token = local_var_configuration
398            .qcs_config
399            .get_bearer_access_token()
400            .await;
401
402        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
403            // the client is configured without any OAuthSession, but this call does not require one.
404            #[cfg(feature = "tracing")]
405            tracing::debug!(
406                "No client credentials found, but this call does not require authentication."
407            );
408        } else {
409            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
410        }
411    }
412
413    let local_var_req = local_var_req_builder.build()?;
414    let local_var_resp = local_var_client.execute(local_var_req).await?;
415
416    let local_var_status = local_var_resp.status();
417
418    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
419        let local_var_content = local_var_resp.text().await?;
420        serde_json::from_str(&local_var_content).map_err(Error::from)
421    } else {
422        let local_var_retry_delay =
423            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
424        let local_var_content = local_var_resp.text().await?;
425        let local_var_entity: Option<GetQuantumProcessorError> =
426            serde_json::from_str(&local_var_content).ok();
427        let local_var_error = ResponseContent {
428            status: local_var_status,
429            content: local_var_content,
430            entity: local_var_entity,
431            retry_delay: local_var_retry_delay,
432        };
433        Err(Error::ResponseError(local_var_error))
434    }
435}
436
437/// Retrieve a single `QuantumProcessor` by ID.
438pub async fn get_quantum_processor(
439    configuration: &configuration::Configuration,
440    quantum_processor_id: &str,
441) -> Result<crate::models::QuantumProcessor, Error<GetQuantumProcessorError>> {
442    let mut backoff = configuration.backoff.clone();
443    let mut refreshed_credentials = false;
444    let method = reqwest::Method::GET;
445    loop {
446        let result =
447            get_quantum_processor_inner(configuration, &mut backoff, quantum_processor_id.clone())
448                .await;
449
450        match result {
451            Ok(result) => return Ok(result),
452            Err(Error::ResponseError(response)) => {
453                if !refreshed_credentials
454                    && matches!(
455                        response.status,
456                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
457                    )
458                {
459                    configuration.qcs_config.refresh().await?;
460                    refreshed_credentials = true;
461                    continue;
462                } else if let Some(duration) = response.retry_delay {
463                    tokio::time::sleep(duration).await;
464                    continue;
465                }
466
467                return Err(Error::ResponseError(response));
468            }
469            Err(Error::Reqwest(error)) => {
470                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
471                    tokio::time::sleep(duration).await;
472                    continue;
473                }
474
475                return Err(Error::Reqwest(error));
476            }
477            Err(Error::Io(error)) => {
478                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
479                    tokio::time::sleep(duration).await;
480                    continue;
481                }
482
483                return Err(Error::Io(error));
484            }
485            Err(error) => return Err(error),
486        }
487    }
488}
489async fn list_instruction_set_architectures_inner(
490    configuration: &configuration::Configuration,
491    backoff: &mut ExponentialBackoff,
492    page_size: Option<i64>,
493    page_token: Option<&str>,
494) -> Result<
495    crate::models::ListInstructionSetArchitectureResponse,
496    Error<ListInstructionSetArchitecturesError>,
497> {
498    let local_var_configuration = configuration;
499
500    let local_var_client = &local_var_configuration.client;
501
502    let local_var_uri_str = format!(
503        "{}/v1/instructionSetArchitectures",
504        local_var_configuration.qcs_config.api_url()
505    );
506    let mut local_var_req_builder =
507        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
508
509    #[cfg(feature = "tracing")]
510    {
511        // Ignore parsing errors if the URL is invalid for some reason.
512        // If it is invalid, it will turn up as an error later when actually making the request.
513        let local_var_do_tracing = local_var_uri_str
514            .parse::<::url::Url>()
515            .ok()
516            .is_none_or(|url| {
517                configuration
518                    .qcs_config
519                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
520            });
521
522        if local_var_do_tracing {
523            ::tracing::debug!(
524                url=%local_var_uri_str,
525                method="GET",
526                "making list_instruction_set_architectures request",
527            );
528        }
529    }
530
531    if let Some(ref local_var_str) = page_size {
532        local_var_req_builder =
533            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
534    }
535    if let Some(ref local_var_str) = page_token {
536        local_var_req_builder =
537            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
538    }
539
540    // Use the QCS Bearer token if a client OAuthSession is present,
541    // but do not require one when the security schema says it is optional.
542    {
543        use qcs_api_client_common::configuration::TokenError;
544
545        #[allow(
546            clippy::nonminimal_bool,
547            clippy::eq_op,
548            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
549        )]
550        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
551
552        let token = local_var_configuration
553            .qcs_config
554            .get_bearer_access_token()
555            .await;
556
557        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
558            // the client is configured without any OAuthSession, but this call does not require one.
559            #[cfg(feature = "tracing")]
560            tracing::debug!(
561                "No client credentials found, but this call does not require authentication."
562            );
563        } else {
564            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
565        }
566    }
567
568    let local_var_req = local_var_req_builder.build()?;
569    let local_var_resp = local_var_client.execute(local_var_req).await?;
570
571    let local_var_status = local_var_resp.status();
572
573    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
574        let local_var_content = local_var_resp.text().await?;
575        serde_json::from_str(&local_var_content).map_err(Error::from)
576    } else {
577        let local_var_retry_delay =
578            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
579        let local_var_content = local_var_resp.text().await?;
580        let local_var_entity: Option<ListInstructionSetArchitecturesError> =
581            serde_json::from_str(&local_var_content).ok();
582        let local_var_error = ResponseContent {
583            status: local_var_status,
584            content: local_var_content,
585            entity: local_var_entity,
586            retry_delay: local_var_retry_delay,
587        };
588        Err(Error::ResponseError(local_var_error))
589    }
590}
591
592pub async fn list_instruction_set_architectures(
593    configuration: &configuration::Configuration,
594    page_size: Option<i64>,
595    page_token: Option<&str>,
596) -> Result<
597    crate::models::ListInstructionSetArchitectureResponse,
598    Error<ListInstructionSetArchitecturesError>,
599> {
600    let mut backoff = configuration.backoff.clone();
601    let mut refreshed_credentials = false;
602    let method = reqwest::Method::GET;
603    loop {
604        let result = list_instruction_set_architectures_inner(
605            configuration,
606            &mut backoff,
607            page_size.clone(),
608            page_token.clone(),
609        )
610        .await;
611
612        match result {
613            Ok(result) => return Ok(result),
614            Err(Error::ResponseError(response)) => {
615                if !refreshed_credentials
616                    && matches!(
617                        response.status,
618                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
619                    )
620                {
621                    configuration.qcs_config.refresh().await?;
622                    refreshed_credentials = true;
623                    continue;
624                } else if let Some(duration) = response.retry_delay {
625                    tokio::time::sleep(duration).await;
626                    continue;
627                }
628
629                return Err(Error::ResponseError(response));
630            }
631            Err(Error::Reqwest(error)) => {
632                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
633                    tokio::time::sleep(duration).await;
634                    continue;
635                }
636
637                return Err(Error::Reqwest(error));
638            }
639            Err(Error::Io(error)) => {
640                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
641                    tokio::time::sleep(duration).await;
642                    continue;
643                }
644
645                return Err(Error::Io(error));
646            }
647            Err(error) => return Err(error),
648        }
649    }
650}
651async fn list_quantum_processor_accessors_inner(
652    configuration: &configuration::Configuration,
653    backoff: &mut ExponentialBackoff,
654    quantum_processor_id: &str,
655    page_size: Option<i64>,
656    page_token: Option<&str>,
657) -> Result<
658    crate::models::ListQuantumProcessorAccessorsResponse,
659    Error<ListQuantumProcessorAccessorsError>,
660> {
661    let local_var_configuration = configuration;
662
663    let local_var_client = &local_var_configuration.client;
664
665    let local_var_uri_str = format!(
666        "{}/v1/quantumProcessors/{quantumProcessorId}/accessors",
667        local_var_configuration.qcs_config.api_url(),
668        quantumProcessorId = crate::apis::urlencode(quantum_processor_id)
669    );
670    let mut local_var_req_builder =
671        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
672
673    #[cfg(feature = "tracing")]
674    {
675        // Ignore parsing errors if the URL is invalid for some reason.
676        // If it is invalid, it will turn up as an error later when actually making the request.
677        let local_var_do_tracing = local_var_uri_str
678            .parse::<::url::Url>()
679            .ok()
680            .is_none_or(|url| {
681                configuration
682                    .qcs_config
683                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
684            });
685
686        if local_var_do_tracing {
687            ::tracing::debug!(
688                url=%local_var_uri_str,
689                method="GET",
690                "making list_quantum_processor_accessors request",
691            );
692        }
693    }
694
695    if let Some(ref local_var_str) = page_size {
696        local_var_req_builder =
697            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
698    }
699    if let Some(ref local_var_str) = page_token {
700        local_var_req_builder =
701            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
702    }
703
704    // Use the QCS Bearer token if a client OAuthSession is present,
705    // but do not require one when the security schema says it is optional.
706    {
707        use qcs_api_client_common::configuration::TokenError;
708
709        #[allow(
710            clippy::nonminimal_bool,
711            clippy::eq_op,
712            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
713        )]
714        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
715
716        let token = local_var_configuration
717            .qcs_config
718            .get_bearer_access_token()
719            .await;
720
721        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
722            // the client is configured without any OAuthSession, but this call does not require one.
723            #[cfg(feature = "tracing")]
724            tracing::debug!(
725                "No client credentials found, but this call does not require authentication."
726            );
727        } else {
728            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
729        }
730    }
731
732    let local_var_req = local_var_req_builder.build()?;
733    let local_var_resp = local_var_client.execute(local_var_req).await?;
734
735    let local_var_status = local_var_resp.status();
736
737    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
738        let local_var_content = local_var_resp.text().await?;
739        serde_json::from_str(&local_var_content).map_err(Error::from)
740    } else {
741        let local_var_retry_delay =
742            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
743        let local_var_content = local_var_resp.text().await?;
744        let local_var_entity: Option<ListQuantumProcessorAccessorsError> =
745            serde_json::from_str(&local_var_content).ok();
746        let local_var_error = ResponseContent {
747            status: local_var_status,
748            content: local_var_content,
749            entity: local_var_entity,
750            retry_delay: local_var_retry_delay,
751        };
752        Err(Error::ResponseError(local_var_error))
753    }
754}
755
756/// List all means of accessing a QuantumProcessor available to the user.
757pub async fn list_quantum_processor_accessors(
758    configuration: &configuration::Configuration,
759    quantum_processor_id: &str,
760    page_size: Option<i64>,
761    page_token: Option<&str>,
762) -> Result<
763    crate::models::ListQuantumProcessorAccessorsResponse,
764    Error<ListQuantumProcessorAccessorsError>,
765> {
766    let mut backoff = configuration.backoff.clone();
767    let mut refreshed_credentials = false;
768    let method = reqwest::Method::GET;
769    loop {
770        let result = list_quantum_processor_accessors_inner(
771            configuration,
772            &mut backoff,
773            quantum_processor_id.clone(),
774            page_size.clone(),
775            page_token.clone(),
776        )
777        .await;
778
779        match result {
780            Ok(result) => return Ok(result),
781            Err(Error::ResponseError(response)) => {
782                if !refreshed_credentials
783                    && matches!(
784                        response.status,
785                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
786                    )
787                {
788                    configuration.qcs_config.refresh().await?;
789                    refreshed_credentials = true;
790                    continue;
791                } else if let Some(duration) = response.retry_delay {
792                    tokio::time::sleep(duration).await;
793                    continue;
794                }
795
796                return Err(Error::ResponseError(response));
797            }
798            Err(Error::Reqwest(error)) => {
799                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
800                    tokio::time::sleep(duration).await;
801                    continue;
802                }
803
804                return Err(Error::Reqwest(error));
805            }
806            Err(Error::Io(error)) => {
807                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
808                    tokio::time::sleep(duration).await;
809                    continue;
810                }
811
812                return Err(Error::Io(error));
813            }
814            Err(error) => return Err(error),
815        }
816    }
817}
818async fn list_quantum_processors_inner(
819    configuration: &configuration::Configuration,
820    backoff: &mut ExponentialBackoff,
821    page_size: Option<i64>,
822    page_token: Option<&str>,
823) -> Result<crate::models::ListQuantumProcessorsResponse, Error<ListQuantumProcessorsError>> {
824    let local_var_configuration = configuration;
825
826    let local_var_client = &local_var_configuration.client;
827
828    let local_var_uri_str = format!(
829        "{}/v1/quantumProcessors",
830        local_var_configuration.qcs_config.api_url()
831    );
832    let mut local_var_req_builder =
833        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
834
835    #[cfg(feature = "tracing")]
836    {
837        // Ignore parsing errors if the URL is invalid for some reason.
838        // If it is invalid, it will turn up as an error later when actually making the request.
839        let local_var_do_tracing = local_var_uri_str
840            .parse::<::url::Url>()
841            .ok()
842            .is_none_or(|url| {
843                configuration
844                    .qcs_config
845                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
846            });
847
848        if local_var_do_tracing {
849            ::tracing::debug!(
850                url=%local_var_uri_str,
851                method="GET",
852                "making list_quantum_processors request",
853            );
854        }
855    }
856
857    if let Some(ref local_var_str) = page_size {
858        local_var_req_builder =
859            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
860    }
861    if let Some(ref local_var_str) = page_token {
862        local_var_req_builder =
863            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
864    }
865
866    // Use the QCS Bearer token if a client OAuthSession is present,
867    // but do not require one when the security schema says it is optional.
868    {
869        use qcs_api_client_common::configuration::TokenError;
870
871        #[allow(
872            clippy::nonminimal_bool,
873            clippy::eq_op,
874            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
875        )]
876        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
877
878        let token = local_var_configuration
879            .qcs_config
880            .get_bearer_access_token()
881            .await;
882
883        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
884            // the client is configured without any OAuthSession, but this call does not require one.
885            #[cfg(feature = "tracing")]
886            tracing::debug!(
887                "No client credentials found, but this call does not require authentication."
888            );
889        } else {
890            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
891        }
892    }
893
894    let local_var_req = local_var_req_builder.build()?;
895    let local_var_resp = local_var_client.execute(local_var_req).await?;
896
897    let local_var_status = local_var_resp.status();
898
899    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
900        let local_var_content = local_var_resp.text().await?;
901        serde_json::from_str(&local_var_content).map_err(Error::from)
902    } else {
903        let local_var_retry_delay =
904            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
905        let local_var_content = local_var_resp.text().await?;
906        let local_var_entity: Option<ListQuantumProcessorsError> =
907            serde_json::from_str(&local_var_content).ok();
908        let local_var_error = ResponseContent {
909            status: local_var_status,
910            content: local_var_content,
911            entity: local_var_entity,
912            retry_delay: local_var_retry_delay,
913        };
914        Err(Error::ResponseError(local_var_error))
915    }
916}
917
918/// List the [`QuantumProcessor`]s that this user is authorized to access.  If no auth token is provided, only public processors will be returned.
919pub async fn list_quantum_processors(
920    configuration: &configuration::Configuration,
921    page_size: Option<i64>,
922    page_token: Option<&str>,
923) -> Result<crate::models::ListQuantumProcessorsResponse, Error<ListQuantumProcessorsError>> {
924    let mut backoff = configuration.backoff.clone();
925    let mut refreshed_credentials = false;
926    let method = reqwest::Method::GET;
927    loop {
928        let result = list_quantum_processors_inner(
929            configuration,
930            &mut backoff,
931            page_size.clone(),
932            page_token.clone(),
933        )
934        .await;
935
936        match result {
937            Ok(result) => return Ok(result),
938            Err(Error::ResponseError(response)) => {
939                if !refreshed_credentials
940                    && matches!(
941                        response.status,
942                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
943                    )
944                {
945                    configuration.qcs_config.refresh().await?;
946                    refreshed_credentials = true;
947                    continue;
948                } else if let Some(duration) = response.retry_delay {
949                    tokio::time::sleep(duration).await;
950                    continue;
951                }
952
953                return Err(Error::ResponseError(response));
954            }
955            Err(Error::Reqwest(error)) => {
956                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
957                    tokio::time::sleep(duration).await;
958                    continue;
959                }
960
961                return Err(Error::Reqwest(error));
962            }
963            Err(Error::Io(error)) => {
964                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
965                    tokio::time::sleep(duration).await;
966                    continue;
967                }
968
969                return Err(Error::Io(error));
970            }
971            Err(error) => return Err(error),
972        }
973    }
974}