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