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    Status404(crate::models::Error),
40    Status422(crate::models::ValidationError),
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    Status404(crate::models::Error),
49    Status422(crate::models::ValidationError),
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    UnknownValue(serde_json::Value),
59}
60
61/// struct for typed errors of method [`list_quantum_processor_accessors`]
62#[derive(Debug, Clone, Serialize, Deserialize)]
63#[serde(untagged)]
64pub enum ListQuantumProcessorAccessorsError {
65    Status422(crate::models::ValidationError),
66    UnknownValue(serde_json::Value),
67}
68
69/// struct for typed errors of method [`list_quantum_processors`]
70#[derive(Debug, Clone, Serialize, Deserialize)]
71#[serde(untagged)]
72pub enum ListQuantumProcessorsError {
73    Status422(crate::models::ValidationError),
74    UnknownValue(serde_json::Value),
75}
76
77async fn get_instruction_set_architecture_inner(
78    configuration: &configuration::Configuration,
79    backoff: &mut ExponentialBackoff,
80    quantum_processor_id: &str,
81) -> Result<crate::models::InstructionSetArchitecture, Error<GetInstructionSetArchitectureError>> {
82    let local_var_configuration = configuration;
83
84    let local_var_client = &local_var_configuration.client;
85
86    let local_var_uri_str = format!(
87        "{}/v1/quantumProcessors/{quantumProcessorId}/instructionSetArchitecture",
88        local_var_configuration.qcs_config.api_url(),
89        quantumProcessorId = crate::apis::urlencode(quantum_processor_id)
90    );
91    let mut local_var_req_builder =
92        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
93
94    #[cfg(feature = "tracing")]
95    {
96        // Ignore parsing errors if the URL is invalid for some reason.
97        // If it is invalid, it will turn up as an error later when actually making the request.
98        let local_var_do_tracing =
99            local_var_uri_str
100                .parse::<::url::Url>()
101                .ok()
102                .map_or(true, |url| {
103                    configuration
104                        .qcs_config
105                        .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
106                });
107
108        if local_var_do_tracing {
109            ::tracing::debug!(
110                url=%local_var_uri_str,
111                method="GET",
112                "making get_instruction_set_architecture request",
113            );
114        }
115    }
116
117    // Use the QCS Bearer token if a client OAuthSession is present,
118    // but do not require one when the security schema says it is optional.
119    {
120        use qcs_api_client_common::configuration::TokenError;
121
122        #[allow(
123            clippy::nonminimal_bool,
124            clippy::eq_op,
125            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
126        )]
127        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
128
129        let token = local_var_configuration
130            .qcs_config
131            .get_bearer_access_token()
132            .await;
133
134        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
135            // the client is configured without any OAuthSession, but this call does not require one.
136            #[cfg(feature = "tracing")]
137            tracing::debug!(
138                "No client credentials found, but this call does not require authentication."
139            );
140        } else {
141            local_var_req_builder = local_var_req_builder.bearer_auth(token?);
142        }
143    }
144
145    let local_var_req = local_var_req_builder.build()?;
146    let local_var_resp = local_var_client.execute(local_var_req).await?;
147
148    let local_var_status = local_var_resp.status();
149
150    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
151        let local_var_content = local_var_resp.text().await?;
152        serde_json::from_str(&local_var_content).map_err(Error::from)
153    } else {
154        let local_var_retry_delay =
155            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
156        let local_var_content = local_var_resp.text().await?;
157        let local_var_entity: Option<GetInstructionSetArchitectureError> =
158            serde_json::from_str(&local_var_content).ok();
159        let local_var_error = ResponseContent {
160            status: local_var_status,
161            content: local_var_content,
162            entity: local_var_entity,
163            retry_delay: local_var_retry_delay,
164        };
165        Err(Error::ResponseError(local_var_error))
166    }
167}
168
169/// Retrieve the Instruction Set Architecture of a QuantumProcessor by ID.
170pub async fn get_instruction_set_architecture(
171    configuration: &configuration::Configuration,
172    quantum_processor_id: &str,
173) -> Result<crate::models::InstructionSetArchitecture, Error<GetInstructionSetArchitectureError>> {
174    let mut backoff = configuration.backoff.clone();
175    let mut refreshed_credentials = false;
176    let method = reqwest::Method::GET;
177    loop {
178        let result = get_instruction_set_architecture_inner(
179            configuration,
180            &mut backoff,
181            quantum_processor_id.clone(),
182        )
183        .await;
184
185        match result {
186            Ok(result) => return Ok(result),
187            Err(Error::ResponseError(response)) => {
188                if !refreshed_credentials
189                    && matches!(
190                        response.status,
191                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
192                    )
193                {
194                    configuration.qcs_config.refresh().await?;
195                    refreshed_credentials = true;
196                    continue;
197                } else if let Some(duration) = response.retry_delay {
198                    tokio::time::sleep(duration).await;
199                    continue;
200                }
201
202                return Err(Error::ResponseError(response));
203            }
204            Err(Error::Reqwest(error)) => {
205                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
206                    tokio::time::sleep(duration).await;
207                    continue;
208                }
209
210                return Err(Error::Reqwest(error));
211            }
212            Err(Error::Io(error)) => {
213                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
214                    tokio::time::sleep(duration).await;
215                    continue;
216                }
217
218                return Err(Error::Io(error));
219            }
220            Err(error) => return Err(error),
221        }
222    }
223}
224async fn get_quantum_processor_inner(
225    configuration: &configuration::Configuration,
226    backoff: &mut ExponentialBackoff,
227    quantum_processor_id: &str,
228) -> Result<crate::models::QuantumProcessor, Error<GetQuantumProcessorError>> {
229    let local_var_configuration = configuration;
230
231    let local_var_client = &local_var_configuration.client;
232
233    let local_var_uri_str = format!(
234        "{}/v1/quantumProcessors/{quantumProcessorId}",
235        local_var_configuration.qcs_config.api_url(),
236        quantumProcessorId = crate::apis::urlencode(quantum_processor_id)
237    );
238    let mut local_var_req_builder =
239        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
240
241    #[cfg(feature = "tracing")]
242    {
243        // Ignore parsing errors if the URL is invalid for some reason.
244        // If it is invalid, it will turn up as an error later when actually making the request.
245        let local_var_do_tracing =
246            local_var_uri_str
247                .parse::<::url::Url>()
248                .ok()
249                .map_or(true, |url| {
250                    configuration
251                        .qcs_config
252                        .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
253                });
254
255        if local_var_do_tracing {
256            ::tracing::debug!(
257                url=%local_var_uri_str,
258                method="GET",
259                "making get_quantum_processor request",
260            );
261        }
262    }
263
264    // Use the QCS Bearer token if a client OAuthSession is present,
265    // but do not require one when the security schema says it is optional.
266    {
267        use qcs_api_client_common::configuration::TokenError;
268
269        #[allow(
270            clippy::nonminimal_bool,
271            clippy::eq_op,
272            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
273        )]
274        let is_jwt_bearer_optional: bool = false || "JWTBearerOptional" == "JWTBearerOptional";
275
276        let token = local_var_configuration
277            .qcs_config
278            .get_bearer_access_token()
279            .await;
280
281        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
282            // the client is configured without any OAuthSession, but this call does not require one.
283            #[cfg(feature = "tracing")]
284            tracing::debug!(
285                "No client credentials found, but this call does not require authentication."
286            );
287        } else {
288            local_var_req_builder = local_var_req_builder.bearer_auth(token?);
289        }
290    }
291
292    let local_var_req = local_var_req_builder.build()?;
293    let local_var_resp = local_var_client.execute(local_var_req).await?;
294
295    let local_var_status = local_var_resp.status();
296
297    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
298        let local_var_content = local_var_resp.text().await?;
299        serde_json::from_str(&local_var_content).map_err(Error::from)
300    } else {
301        let local_var_retry_delay =
302            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
303        let local_var_content = local_var_resp.text().await?;
304        let local_var_entity: Option<GetQuantumProcessorError> =
305            serde_json::from_str(&local_var_content).ok();
306        let local_var_error = ResponseContent {
307            status: local_var_status,
308            content: local_var_content,
309            entity: local_var_entity,
310            retry_delay: local_var_retry_delay,
311        };
312        Err(Error::ResponseError(local_var_error))
313    }
314}
315
316/// Retrieve a single QuantumProcessor by ID.
317pub async fn get_quantum_processor(
318    configuration: &configuration::Configuration,
319    quantum_processor_id: &str,
320) -> Result<crate::models::QuantumProcessor, Error<GetQuantumProcessorError>> {
321    let mut backoff = configuration.backoff.clone();
322    let mut refreshed_credentials = false;
323    let method = reqwest::Method::GET;
324    loop {
325        let result =
326            get_quantum_processor_inner(configuration, &mut backoff, quantum_processor_id.clone())
327                .await;
328
329        match result {
330            Ok(result) => return Ok(result),
331            Err(Error::ResponseError(response)) => {
332                if !refreshed_credentials
333                    && matches!(
334                        response.status,
335                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
336                    )
337                {
338                    configuration.qcs_config.refresh().await?;
339                    refreshed_credentials = true;
340                    continue;
341                } else if let Some(duration) = response.retry_delay {
342                    tokio::time::sleep(duration).await;
343                    continue;
344                }
345
346                return Err(Error::ResponseError(response));
347            }
348            Err(Error::Reqwest(error)) => {
349                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
350                    tokio::time::sleep(duration).await;
351                    continue;
352                }
353
354                return Err(Error::Reqwest(error));
355            }
356            Err(Error::Io(error)) => {
357                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
358                    tokio::time::sleep(duration).await;
359                    continue;
360                }
361
362                return Err(Error::Io(error));
363            }
364            Err(error) => return Err(error),
365        }
366    }
367}
368async fn list_instruction_set_architectures_inner(
369    configuration: &configuration::Configuration,
370    backoff: &mut ExponentialBackoff,
371    page_size: Option<i64>,
372    page_token: Option<&str>,
373) -> Result<
374    crate::models::ListInstructionSetArchitectureResponse,
375    Error<ListInstructionSetArchitecturesError>,
376> {
377    let local_var_configuration = configuration;
378
379    let local_var_client = &local_var_configuration.client;
380
381    let local_var_uri_str = format!(
382        "{}/v1/instructionSetArchitectures",
383        local_var_configuration.qcs_config.api_url()
384    );
385    let mut local_var_req_builder =
386        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
387
388    #[cfg(feature = "tracing")]
389    {
390        // Ignore parsing errors if the URL is invalid for some reason.
391        // If it is invalid, it will turn up as an error later when actually making the request.
392        let local_var_do_tracing =
393            local_var_uri_str
394                .parse::<::url::Url>()
395                .ok()
396                .map_or(true, |url| {
397                    configuration
398                        .qcs_config
399                        .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
400                });
401
402        if local_var_do_tracing {
403            ::tracing::debug!(
404                url=%local_var_uri_str,
405                method="GET",
406                "making list_instruction_set_architectures request",
407            );
408        }
409    }
410
411    if let Some(ref local_var_str) = page_size {
412        local_var_req_builder =
413            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
414    }
415    if let Some(ref local_var_str) = page_token {
416        local_var_req_builder =
417            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
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?);
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
453    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
454        let local_var_content = local_var_resp.text().await?;
455        serde_json::from_str(&local_var_content).map_err(Error::from)
456    } else {
457        let local_var_retry_delay =
458            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
459        let local_var_content = local_var_resp.text().await?;
460        let local_var_entity: Option<ListInstructionSetArchitecturesError> =
461            serde_json::from_str(&local_var_content).ok();
462        let local_var_error = ResponseContent {
463            status: local_var_status,
464            content: local_var_content,
465            entity: local_var_entity,
466            retry_delay: local_var_retry_delay,
467        };
468        Err(Error::ResponseError(local_var_error))
469    }
470}
471
472/// Retrieve all Instruction Set Architectures available to the user.
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 all QuantumProcessors available to the user.
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}