Skip to main content

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