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