Skip to main content

qcs_api_client_openapi/apis/
endpoints_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 [`create_endpoint`]
40#[cfg(feature = "clap")]
41#[derive(Debug, clap::Args)]
42pub struct CreateEndpointClapParams {
43    pub create_endpoint_parameters: JsonMaybeStdin<crate::models::CreateEndpointParameters>,
44}
45
46#[cfg(feature = "clap")]
47impl CreateEndpointClapParams {
48    pub async fn execute(
49        self,
50        configuration: &configuration::Configuration,
51    ) -> Result<models::Endpoint, miette::Error> {
52        let request = self.create_endpoint_parameters.into_inner().into_inner();
53
54        create_endpoint(configuration, request)
55            .await
56            .into_diagnostic()
57    }
58}
59
60/// Serialize command-line arguments for [`delete_endpoint`]
61#[cfg(feature = "clap")]
62#[derive(Debug, clap::Args)]
63pub struct DeleteEndpointClapParams {
64    #[arg(long)]
65    pub endpoint_id: String,
66}
67
68#[cfg(feature = "clap")]
69impl DeleteEndpointClapParams {
70    pub async fn execute(
71        self,
72        configuration: &configuration::Configuration,
73    ) -> Result<(), miette::Error> {
74        delete_endpoint(configuration, self.endpoint_id.as_str())
75            .await
76            .into_diagnostic()
77    }
78}
79
80/// Serialize command-line arguments for [`get_default_endpoint`]
81#[cfg(feature = "clap")]
82#[derive(Debug, clap::Args)]
83pub struct GetDefaultEndpointClapParams {
84    /// Public identifier for a quantum processor [example: Aspen-1]
85    #[arg(long)]
86    pub quantum_processor_id: String,
87}
88
89#[cfg(feature = "clap")]
90impl GetDefaultEndpointClapParams {
91    pub async fn execute(
92        self,
93        configuration: &configuration::Configuration,
94    ) -> Result<models::Endpoint, miette::Error> {
95        get_default_endpoint(configuration, self.quantum_processor_id.as_str())
96            .await
97            .into_diagnostic()
98    }
99}
100
101/// Serialize command-line arguments for [`get_endpoint`]
102#[cfg(feature = "clap")]
103#[derive(Debug, clap::Args)]
104pub struct GetEndpointClapParams {
105    #[arg(long)]
106    pub endpoint_id: String,
107}
108
109#[cfg(feature = "clap")]
110impl GetEndpointClapParams {
111    pub async fn execute(
112        self,
113        configuration: &configuration::Configuration,
114    ) -> Result<models::Endpoint, miette::Error> {
115        get_endpoint(configuration, self.endpoint_id.as_str())
116            .await
117            .into_diagnostic()
118    }
119}
120
121/// Serialize command-line arguments for [`list_endpoints`]
122#[cfg(feature = "clap")]
123#[derive(Debug, clap::Args)]
124pub struct ListEndpointsClapParams {
125    /// Filtering logic specified using [rule-engine](https://zerosteiner.github.io/rule-engine/syntax.html) grammar
126    #[arg(long)]
127    pub filter: Option<String>,
128    #[arg(long)]
129    pub page_size: Option<i64>,
130    #[arg(long)]
131    pub page_token: Option<String>,
132}
133
134#[cfg(feature = "clap")]
135impl ListEndpointsClapParams {
136    pub async fn execute(
137        self,
138        configuration: &configuration::Configuration,
139    ) -> Result<models::ListEndpointsResponse, miette::Error> {
140        list_endpoints(
141            configuration,
142            self.filter.as_deref(),
143            self.page_size,
144            self.page_token.as_deref(),
145        )
146        .await
147        .into_diagnostic()
148    }
149}
150
151/// Serialize command-line arguments for [`restart_endpoint`]
152#[cfg(feature = "clap")]
153#[derive(Debug, clap::Args)]
154pub struct RestartEndpointClapParams {
155    #[arg(long)]
156    pub endpoint_id: String,
157    pub restart_endpoint_request: Option<JsonMaybeStdin<crate::models::RestartEndpointRequest>>,
158}
159
160#[cfg(feature = "clap")]
161impl RestartEndpointClapParams {
162    pub async fn execute(
163        self,
164        configuration: &configuration::Configuration,
165    ) -> Result<(), miette::Error> {
166        let request = self
167            .restart_endpoint_request
168            .map(|body| body.into_inner().into_inner());
169
170        restart_endpoint(configuration, self.endpoint_id.as_str(), request)
171            .await
172            .into_diagnostic()
173    }
174}
175
176/// struct for typed errors of method [`create_endpoint`]
177#[derive(Debug, Clone, Serialize, Deserialize)]
178#[serde(untagged)]
179pub enum CreateEndpointError {
180    Status400(models::Error),
181    Status404(models::Error),
182    Status422(models::ValidationError),
183    UnknownValue(serde_json::Value),
184}
185
186/// struct for typed errors of method [`delete_endpoint`]
187#[derive(Debug, Clone, Serialize, Deserialize)]
188#[serde(untagged)]
189pub enum DeleteEndpointError {
190    Status403(models::Error),
191    Status404(models::Error),
192    Status422(models::ValidationError),
193    UnknownValue(serde_json::Value),
194}
195
196/// struct for typed errors of method [`get_default_endpoint`]
197#[derive(Debug, Clone, Serialize, Deserialize)]
198#[serde(untagged)]
199pub enum GetDefaultEndpointError {
200    Status404(models::Error),
201    Status422(models::ValidationError),
202    UnknownValue(serde_json::Value),
203}
204
205/// struct for typed errors of method [`get_endpoint`]
206#[derive(Debug, Clone, Serialize, Deserialize)]
207#[serde(untagged)]
208pub enum GetEndpointError {
209    Status404(models::Error),
210    Status422(models::ValidationError),
211    UnknownValue(serde_json::Value),
212}
213
214/// struct for typed errors of method [`list_endpoints`]
215#[derive(Debug, Clone, Serialize, Deserialize)]
216#[serde(untagged)]
217pub enum ListEndpointsError {
218    Status422(models::ValidationError),
219    UnknownValue(serde_json::Value),
220}
221
222/// struct for typed errors of method [`restart_endpoint`]
223#[derive(Debug, Clone, Serialize, Deserialize)]
224#[serde(untagged)]
225pub enum RestartEndpointError {
226    Status403(models::Error),
227    Status422(models::ValidationError),
228    UnknownValue(serde_json::Value),
229}
230
231async fn create_endpoint_inner(
232    configuration: &configuration::Configuration,
233    backoff: &mut ExponentialBackoff,
234    create_endpoint_parameters: crate::models::CreateEndpointParameters,
235) -> Result<models::Endpoint, Error<CreateEndpointError>> {
236    let local_var_configuration = configuration;
237    // add a prefix to parameters to efficiently prevent name collisions
238    let p_body_create_endpoint_parameters = create_endpoint_parameters;
239
240    let local_var_client = &local_var_configuration.client;
241
242    let local_var_uri_str = format!(
243        "{}/v1/endpoints",
244        local_var_configuration.qcs_config.api_url()
245    );
246    let mut local_var_req_builder =
247        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
248
249    #[cfg(feature = "tracing")]
250    {
251        // Ignore parsing errors if the URL is invalid for some reason.
252        // If it is invalid, it will turn up as an error later when actually making the request.
253        let local_var_do_tracing = local_var_uri_str
254            .parse::<::url::Url>()
255            .ok()
256            .is_none_or(|url| {
257                configuration
258                    .qcs_config
259                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
260            });
261
262        if local_var_do_tracing {
263            ::tracing::debug!(
264                url=%local_var_uri_str,
265                method="POST",
266                "making create_endpoint request",
267            );
268        }
269    }
270
271    // Use the QCS Bearer token if a client OAuthSession is present,
272    // but do not require one when the security schema says it is optional.
273    {
274        use qcs_api_client_common::configuration::TokenError;
275
276        #[allow(
277            clippy::nonminimal_bool,
278            clippy::eq_op,
279            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
280        )]
281        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
282
283        let token = local_var_configuration
284            .qcs_config
285            .get_bearer_access_token()
286            .await;
287
288        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
289            // the client is configured without any OAuthSession, but this call does not require one.
290            #[cfg(feature = "tracing")]
291            tracing::debug!(
292                "No client credentials found, but this call does not require authentication."
293            );
294        } else {
295            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
296        }
297    }
298
299    local_var_req_builder = local_var_req_builder.json(&p_body_create_endpoint_parameters);
300
301    let local_var_req = local_var_req_builder.build()?;
302    let local_var_resp = local_var_client.execute(local_var_req).await?;
303
304    let local_var_status = local_var_resp.status();
305    let local_var_raw_content_type = local_var_resp
306        .headers()
307        .get("content-type")
308        .and_then(|v| v.to_str().ok())
309        .unwrap_or("application/octet-stream")
310        .to_string();
311    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
312
313    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
314        let local_var_content = local_var_resp.text().await?;
315        match local_var_content_type {
316            ContentType::Json => serde_path_to_error::deserialize(
317                &mut serde_json::Deserializer::from_str(&local_var_content),
318            )
319            .map_err(Error::from),
320            ContentType::Text => Err(Error::InvalidContentType {
321                content_type: local_var_raw_content_type,
322                return_type: "models::Endpoint",
323            }),
324            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
325                content_type: unknown_type,
326                return_type: "models::Endpoint",
327            }),
328        }
329    } else {
330        let local_var_retry_delay =
331            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
332        let local_var_content = local_var_resp.text().await?;
333        let local_var_entity: Option<CreateEndpointError> =
334            serde_json::from_str(&local_var_content).ok();
335        let local_var_error = ResponseContent {
336            status: local_var_status,
337            content: local_var_content,
338            entity: local_var_entity,
339            retry_delay: local_var_retry_delay,
340        };
341        Err(Error::ResponseError(local_var_error))
342    }
343}
344
345/// Create an endpoint associated with your user account.
346pub async fn create_endpoint(
347    configuration: &configuration::Configuration,
348    create_endpoint_parameters: crate::models::CreateEndpointParameters,
349) -> Result<models::Endpoint, Error<CreateEndpointError>> {
350    let mut backoff = configuration.backoff.clone();
351    let mut refreshed_credentials = false;
352    let method = reqwest::Method::POST;
353    loop {
354        let result = create_endpoint_inner(
355            configuration,
356            &mut backoff,
357            create_endpoint_parameters.clone(),
358        )
359        .await;
360
361        match result {
362            Ok(result) => return Ok(result),
363            Err(Error::ResponseError(response)) => {
364                if !refreshed_credentials
365                    && matches!(
366                        response.status,
367                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
368                    )
369                {
370                    configuration.qcs_config.refresh().await?;
371                    refreshed_credentials = true;
372                    continue;
373                } else if let Some(duration) = response.retry_delay {
374                    tokio::time::sleep(duration).await;
375                    continue;
376                }
377
378                return Err(Error::ResponseError(response));
379            }
380            Err(Error::Reqwest(error)) => {
381                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
382                    tokio::time::sleep(duration).await;
383                    continue;
384                }
385
386                return Err(Error::Reqwest(error));
387            }
388            Err(Error::Io(error)) => {
389                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
390                    tokio::time::sleep(duration).await;
391                    continue;
392                }
393
394                return Err(Error::Io(error));
395            }
396            Err(error) => return Err(error),
397        }
398    }
399}
400async fn delete_endpoint_inner(
401    configuration: &configuration::Configuration,
402    backoff: &mut ExponentialBackoff,
403    endpoint_id: &str,
404) -> Result<(), Error<DeleteEndpointError>> {
405    let local_var_configuration = configuration;
406    // add a prefix to parameters to efficiently prevent name collisions
407    let p_path_endpoint_id = endpoint_id;
408
409    let local_var_client = &local_var_configuration.client;
410
411    let local_var_uri_str = format!(
412        "{}/v1/endpoints/{endpointId}",
413        local_var_configuration.qcs_config.api_url(),
414        endpointId = crate::apis::urlencode(p_path_endpoint_id)
415    );
416    let mut local_var_req_builder =
417        local_var_client.request(reqwest::Method::DELETE, local_var_uri_str.as_str());
418
419    #[cfg(feature = "tracing")]
420    {
421        // Ignore parsing errors if the URL is invalid for some reason.
422        // If it is invalid, it will turn up as an error later when actually making the request.
423        let local_var_do_tracing = local_var_uri_str
424            .parse::<::url::Url>()
425            .ok()
426            .is_none_or(|url| {
427                configuration
428                    .qcs_config
429                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
430            });
431
432        if local_var_do_tracing {
433            ::tracing::debug!(
434                url=%local_var_uri_str,
435                method="DELETE",
436                "making delete_endpoint request",
437            );
438        }
439    }
440
441    // Use the QCS Bearer token if a client OAuthSession is present,
442    // but do not require one when the security schema says it is optional.
443    {
444        use qcs_api_client_common::configuration::TokenError;
445
446        #[allow(
447            clippy::nonminimal_bool,
448            clippy::eq_op,
449            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
450        )]
451        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
452
453        let token = local_var_configuration
454            .qcs_config
455            .get_bearer_access_token()
456            .await;
457
458        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
459            // the client is configured without any OAuthSession, but this call does not require one.
460            #[cfg(feature = "tracing")]
461            tracing::debug!(
462                "No client credentials found, but this call does not require authentication."
463            );
464        } else {
465            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
466        }
467    }
468
469    let local_var_req = local_var_req_builder.build()?;
470    let local_var_resp = local_var_client.execute(local_var_req).await?;
471
472    let local_var_status = local_var_resp.status();
473
474    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
475        Ok(())
476    } else {
477        let local_var_retry_delay =
478            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
479        let local_var_content = local_var_resp.text().await?;
480        let local_var_entity: Option<DeleteEndpointError> =
481            serde_json::from_str(&local_var_content).ok();
482        let local_var_error = ResponseContent {
483            status: local_var_status,
484            content: local_var_content,
485            entity: local_var_entity,
486            retry_delay: local_var_retry_delay,
487        };
488        Err(Error::ResponseError(local_var_error))
489    }
490}
491
492/// Delete an endpoint, releasing its resources. This operation is not reversible.
493pub async fn delete_endpoint(
494    configuration: &configuration::Configuration,
495    endpoint_id: &str,
496) -> Result<(), Error<DeleteEndpointError>> {
497    let mut backoff = configuration.backoff.clone();
498    let mut refreshed_credentials = false;
499    let method = reqwest::Method::DELETE;
500    loop {
501        let result = delete_endpoint_inner(configuration, &mut backoff, endpoint_id.clone()).await;
502
503        match result {
504            Ok(result) => return Ok(result),
505            Err(Error::ResponseError(response)) => {
506                if !refreshed_credentials
507                    && matches!(
508                        response.status,
509                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
510                    )
511                {
512                    configuration.qcs_config.refresh().await?;
513                    refreshed_credentials = true;
514                    continue;
515                } else if let Some(duration) = response.retry_delay {
516                    tokio::time::sleep(duration).await;
517                    continue;
518                }
519
520                return Err(Error::ResponseError(response));
521            }
522            Err(Error::Reqwest(error)) => {
523                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
524                    tokio::time::sleep(duration).await;
525                    continue;
526                }
527
528                return Err(Error::Reqwest(error));
529            }
530            Err(Error::Io(error)) => {
531                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
532                    tokio::time::sleep(duration).await;
533                    continue;
534                }
535
536                return Err(Error::Io(error));
537            }
538            Err(error) => return Err(error),
539        }
540    }
541}
542async fn get_default_endpoint_inner(
543    configuration: &configuration::Configuration,
544    backoff: &mut ExponentialBackoff,
545    quantum_processor_id: &str,
546) -> Result<models::Endpoint, Error<GetDefaultEndpointError>> {
547    let local_var_configuration = configuration;
548    // add a prefix to parameters to efficiently prevent name collisions
549    let p_path_quantum_processor_id = quantum_processor_id;
550
551    let local_var_client = &local_var_configuration.client;
552
553    let local_var_uri_str = format!(
554        "{}/v1/quantumProcessors/{quantumProcessorId}/endpoints:getDefault",
555        local_var_configuration.qcs_config.api_url(),
556        quantumProcessorId = crate::apis::urlencode(p_path_quantum_processor_id)
557    );
558    let mut local_var_req_builder =
559        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
560
561    #[cfg(feature = "tracing")]
562    {
563        // Ignore parsing errors if the URL is invalid for some reason.
564        // If it is invalid, it will turn up as an error later when actually making the request.
565        let local_var_do_tracing = local_var_uri_str
566            .parse::<::url::Url>()
567            .ok()
568            .is_none_or(|url| {
569                configuration
570                    .qcs_config
571                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
572            });
573
574        if local_var_do_tracing {
575            ::tracing::debug!(
576                url=%local_var_uri_str,
577                method="GET",
578                "making get_default_endpoint request",
579            );
580        }
581    }
582
583    // Use the QCS Bearer token if a client OAuthSession is present,
584    // but do not require one when the security schema says it is optional.
585    {
586        use qcs_api_client_common::configuration::TokenError;
587
588        #[allow(
589            clippy::nonminimal_bool,
590            clippy::eq_op,
591            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
592        )]
593        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
594
595        let token = local_var_configuration
596            .qcs_config
597            .get_bearer_access_token()
598            .await;
599
600        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
601            // the client is configured without any OAuthSession, but this call does not require one.
602            #[cfg(feature = "tracing")]
603            tracing::debug!(
604                "No client credentials found, but this call does not require authentication."
605            );
606        } else {
607            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
608        }
609    }
610
611    let local_var_req = local_var_req_builder.build()?;
612    let local_var_resp = local_var_client.execute(local_var_req).await?;
613
614    let local_var_status = local_var_resp.status();
615    let local_var_raw_content_type = local_var_resp
616        .headers()
617        .get("content-type")
618        .and_then(|v| v.to_str().ok())
619        .unwrap_or("application/octet-stream")
620        .to_string();
621    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
622
623    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
624        let local_var_content = local_var_resp.text().await?;
625        match local_var_content_type {
626            ContentType::Json => serde_path_to_error::deserialize(
627                &mut serde_json::Deserializer::from_str(&local_var_content),
628            )
629            .map_err(Error::from),
630            ContentType::Text => Err(Error::InvalidContentType {
631                content_type: local_var_raw_content_type,
632                return_type: "models::Endpoint",
633            }),
634            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
635                content_type: unknown_type,
636                return_type: "models::Endpoint",
637            }),
638        }
639    } else {
640        let local_var_retry_delay =
641            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
642        let local_var_content = local_var_resp.text().await?;
643        let local_var_entity: Option<GetDefaultEndpointError> =
644            serde_json::from_str(&local_var_content).ok();
645        let local_var_error = ResponseContent {
646            status: local_var_status,
647            content: local_var_content,
648            entity: local_var_entity,
649            retry_delay: local_var_retry_delay,
650        };
651        Err(Error::ResponseError(local_var_error))
652    }
653}
654
655/// Retrieve the endpoint set as \"default\" for the given Quantum Processor.  If no endpoint is set as the default, return \"not found.\"
656pub async fn get_default_endpoint(
657    configuration: &configuration::Configuration,
658    quantum_processor_id: &str,
659) -> Result<models::Endpoint, Error<GetDefaultEndpointError>> {
660    let mut backoff = configuration.backoff.clone();
661    let mut refreshed_credentials = false;
662    let method = reqwest::Method::GET;
663    loop {
664        let result =
665            get_default_endpoint_inner(configuration, &mut backoff, quantum_processor_id.clone())
666                .await;
667
668        match result {
669            Ok(result) => return Ok(result),
670            Err(Error::ResponseError(response)) => {
671                if !refreshed_credentials
672                    && matches!(
673                        response.status,
674                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
675                    )
676                {
677                    configuration.qcs_config.refresh().await?;
678                    refreshed_credentials = true;
679                    continue;
680                } else if let Some(duration) = response.retry_delay {
681                    tokio::time::sleep(duration).await;
682                    continue;
683                }
684
685                return Err(Error::ResponseError(response));
686            }
687            Err(Error::Reqwest(error)) => {
688                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
689                    tokio::time::sleep(duration).await;
690                    continue;
691                }
692
693                return Err(Error::Reqwest(error));
694            }
695            Err(Error::Io(error)) => {
696                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
697                    tokio::time::sleep(duration).await;
698                    continue;
699                }
700
701                return Err(Error::Io(error));
702            }
703            Err(error) => return Err(error),
704        }
705    }
706}
707async fn get_endpoint_inner(
708    configuration: &configuration::Configuration,
709    backoff: &mut ExponentialBackoff,
710    endpoint_id: &str,
711) -> Result<models::Endpoint, Error<GetEndpointError>> {
712    let local_var_configuration = configuration;
713    // add a prefix to parameters to efficiently prevent name collisions
714    let p_path_endpoint_id = endpoint_id;
715
716    let local_var_client = &local_var_configuration.client;
717
718    let local_var_uri_str = format!(
719        "{}/v1/endpoints/{endpointId}",
720        local_var_configuration.qcs_config.api_url(),
721        endpointId = crate::apis::urlencode(p_path_endpoint_id)
722    );
723    let mut local_var_req_builder =
724        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
725
726    #[cfg(feature = "tracing")]
727    {
728        // Ignore parsing errors if the URL is invalid for some reason.
729        // If it is invalid, it will turn up as an error later when actually making the request.
730        let local_var_do_tracing = local_var_uri_str
731            .parse::<::url::Url>()
732            .ok()
733            .is_none_or(|url| {
734                configuration
735                    .qcs_config
736                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
737            });
738
739        if local_var_do_tracing {
740            ::tracing::debug!(
741                url=%local_var_uri_str,
742                method="GET",
743                "making get_endpoint request",
744            );
745        }
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 || "JWTBearer" == "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::Endpoint",
798            }),
799            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
800                content_type: unknown_type,
801                return_type: "models::Endpoint",
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<GetEndpointError> =
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
820/// Retrieve a specific endpoint by its ID.
821pub async fn get_endpoint(
822    configuration: &configuration::Configuration,
823    endpoint_id: &str,
824) -> Result<models::Endpoint, Error<GetEndpointError>> {
825    let mut backoff = configuration.backoff.clone();
826    let mut refreshed_credentials = false;
827    let method = reqwest::Method::GET;
828    loop {
829        let result = get_endpoint_inner(configuration, &mut backoff, endpoint_id.clone()).await;
830
831        match result {
832            Ok(result) => return Ok(result),
833            Err(Error::ResponseError(response)) => {
834                if !refreshed_credentials
835                    && matches!(
836                        response.status,
837                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
838                    )
839                {
840                    configuration.qcs_config.refresh().await?;
841                    refreshed_credentials = true;
842                    continue;
843                } else if let Some(duration) = response.retry_delay {
844                    tokio::time::sleep(duration).await;
845                    continue;
846                }
847
848                return Err(Error::ResponseError(response));
849            }
850            Err(Error::Reqwest(error)) => {
851                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
852                    tokio::time::sleep(duration).await;
853                    continue;
854                }
855
856                return Err(Error::Reqwest(error));
857            }
858            Err(Error::Io(error)) => {
859                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
860                    tokio::time::sleep(duration).await;
861                    continue;
862                }
863
864                return Err(Error::Io(error));
865            }
866            Err(error) => return Err(error),
867        }
868    }
869}
870async fn list_endpoints_inner(
871    configuration: &configuration::Configuration,
872    backoff: &mut ExponentialBackoff,
873    filter: Option<&str>,
874    page_size: Option<i64>,
875    page_token: Option<&str>,
876) -> Result<models::ListEndpointsResponse, Error<ListEndpointsError>> {
877    let local_var_configuration = configuration;
878    // add a prefix to parameters to efficiently prevent name collisions
879    let p_query_filter = filter;
880    let p_query_page_size = page_size;
881    let p_query_page_token = page_token;
882
883    let local_var_client = &local_var_configuration.client;
884
885    let local_var_uri_str = format!(
886        "{}/v1/endpoints",
887        local_var_configuration.qcs_config.api_url()
888    );
889    let mut local_var_req_builder =
890        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
891
892    #[cfg(feature = "tracing")]
893    {
894        // Ignore parsing errors if the URL is invalid for some reason.
895        // If it is invalid, it will turn up as an error later when actually making the request.
896        let local_var_do_tracing = local_var_uri_str
897            .parse::<::url::Url>()
898            .ok()
899            .is_none_or(|url| {
900                configuration
901                    .qcs_config
902                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
903            });
904
905        if local_var_do_tracing {
906            ::tracing::debug!(
907                url=%local_var_uri_str,
908                method="GET",
909                "making list_endpoints request",
910            );
911        }
912    }
913
914    if let Some(ref local_var_str) = p_query_filter {
915        local_var_req_builder =
916            local_var_req_builder.query(&[("filter", &local_var_str.to_string())]);
917    }
918    if let Some(ref local_var_str) = p_query_page_size {
919        local_var_req_builder =
920            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
921    }
922    if let Some(ref local_var_str) = p_query_page_token {
923        local_var_req_builder =
924            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
925    }
926
927    // Use the QCS Bearer token if a client OAuthSession is present,
928    // but do not require one when the security schema says it is optional.
929    {
930        use qcs_api_client_common::configuration::TokenError;
931
932        #[allow(
933            clippy::nonminimal_bool,
934            clippy::eq_op,
935            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
936        )]
937        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
938
939        let token = local_var_configuration
940            .qcs_config
941            .get_bearer_access_token()
942            .await;
943
944        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
945            // the client is configured without any OAuthSession, but this call does not require one.
946            #[cfg(feature = "tracing")]
947            tracing::debug!(
948                "No client credentials found, but this call does not require authentication."
949            );
950        } else {
951            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
952        }
953    }
954
955    let local_var_req = local_var_req_builder.build()?;
956    let local_var_resp = local_var_client.execute(local_var_req).await?;
957
958    let local_var_status = local_var_resp.status();
959    let local_var_raw_content_type = local_var_resp
960        .headers()
961        .get("content-type")
962        .and_then(|v| v.to_str().ok())
963        .unwrap_or("application/octet-stream")
964        .to_string();
965    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
966
967    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
968        let local_var_content = local_var_resp.text().await?;
969        match local_var_content_type {
970            ContentType::Json => serde_path_to_error::deserialize(
971                &mut serde_json::Deserializer::from_str(&local_var_content),
972            )
973            .map_err(Error::from),
974            ContentType::Text => Err(Error::InvalidContentType {
975                content_type: local_var_raw_content_type,
976                return_type: "models::ListEndpointsResponse",
977            }),
978            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
979                content_type: unknown_type,
980                return_type: "models::ListEndpointsResponse",
981            }),
982        }
983    } else {
984        let local_var_retry_delay =
985            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
986        let local_var_content = local_var_resp.text().await?;
987        let local_var_entity: Option<ListEndpointsError> =
988            serde_json::from_str(&local_var_content).ok();
989        let local_var_error = ResponseContent {
990            status: local_var_status,
991            content: local_var_content,
992            entity: local_var_entity,
993            retry_delay: local_var_retry_delay,
994        };
995        Err(Error::ResponseError(local_var_error))
996    }
997}
998
999/// List all endpoints, optionally filtering by attribute.
1000pub async fn list_endpoints(
1001    configuration: &configuration::Configuration,
1002    filter: Option<&str>,
1003    page_size: Option<i64>,
1004    page_token: Option<&str>,
1005) -> Result<models::ListEndpointsResponse, Error<ListEndpointsError>> {
1006    let mut backoff = configuration.backoff.clone();
1007    let mut refreshed_credentials = false;
1008    let method = reqwest::Method::GET;
1009    loop {
1010        let result = list_endpoints_inner(
1011            configuration,
1012            &mut backoff,
1013            filter.clone(),
1014            page_size.clone(),
1015            page_token.clone(),
1016        )
1017        .await;
1018
1019        match result {
1020            Ok(result) => return Ok(result),
1021            Err(Error::ResponseError(response)) => {
1022                if !refreshed_credentials
1023                    && matches!(
1024                        response.status,
1025                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1026                    )
1027                {
1028                    configuration.qcs_config.refresh().await?;
1029                    refreshed_credentials = true;
1030                    continue;
1031                } else if let Some(duration) = response.retry_delay {
1032                    tokio::time::sleep(duration).await;
1033                    continue;
1034                }
1035
1036                return Err(Error::ResponseError(response));
1037            }
1038            Err(Error::Reqwest(error)) => {
1039                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1040                    tokio::time::sleep(duration).await;
1041                    continue;
1042                }
1043
1044                return Err(Error::Reqwest(error));
1045            }
1046            Err(Error::Io(error)) => {
1047                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1048                    tokio::time::sleep(duration).await;
1049                    continue;
1050                }
1051
1052                return Err(Error::Io(error));
1053            }
1054            Err(error) => return Err(error),
1055        }
1056    }
1057}
1058async fn restart_endpoint_inner(
1059    configuration: &configuration::Configuration,
1060    backoff: &mut ExponentialBackoff,
1061    endpoint_id: &str,
1062    restart_endpoint_request: Option<crate::models::RestartEndpointRequest>,
1063) -> Result<(), Error<RestartEndpointError>> {
1064    let local_var_configuration = configuration;
1065    // add a prefix to parameters to efficiently prevent name collisions
1066    let p_path_endpoint_id = endpoint_id;
1067    let p_body_restart_endpoint_request = restart_endpoint_request;
1068
1069    let local_var_client = &local_var_configuration.client;
1070
1071    let local_var_uri_str = format!(
1072        "{}/v1/endpoints/{endpointId}:restart",
1073        local_var_configuration.qcs_config.api_url(),
1074        endpointId = crate::apis::urlencode(p_path_endpoint_id)
1075    );
1076    let mut local_var_req_builder =
1077        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
1078
1079    #[cfg(feature = "tracing")]
1080    {
1081        // Ignore parsing errors if the URL is invalid for some reason.
1082        // If it is invalid, it will turn up as an error later when actually making the request.
1083        let local_var_do_tracing = local_var_uri_str
1084            .parse::<::url::Url>()
1085            .ok()
1086            .is_none_or(|url| {
1087                configuration
1088                    .qcs_config
1089                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
1090            });
1091
1092        if local_var_do_tracing {
1093            ::tracing::debug!(
1094                url=%local_var_uri_str,
1095                method="POST",
1096                "making restart_endpoint request",
1097            );
1098        }
1099    }
1100
1101    // Use the QCS Bearer token if a client OAuthSession is present,
1102    // but do not require one when the security schema says it is optional.
1103    {
1104        use qcs_api_client_common::configuration::TokenError;
1105
1106        #[allow(
1107            clippy::nonminimal_bool,
1108            clippy::eq_op,
1109            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1110        )]
1111        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1112
1113        let token = local_var_configuration
1114            .qcs_config
1115            .get_bearer_access_token()
1116            .await;
1117
1118        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1119            // the client is configured without any OAuthSession, but this call does not require one.
1120            #[cfg(feature = "tracing")]
1121            tracing::debug!(
1122                "No client credentials found, but this call does not require authentication."
1123            );
1124        } else {
1125            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1126        }
1127    }
1128
1129    local_var_req_builder = local_var_req_builder.json(&p_body_restart_endpoint_request);
1130
1131    let local_var_req = local_var_req_builder.build()?;
1132    let local_var_resp = local_var_client.execute(local_var_req).await?;
1133
1134    let local_var_status = local_var_resp.status();
1135
1136    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1137        Ok(())
1138    } else {
1139        let local_var_retry_delay =
1140            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1141        let local_var_content = local_var_resp.text().await?;
1142        let local_var_entity: Option<RestartEndpointError> =
1143            serde_json::from_str(&local_var_content).ok();
1144        let local_var_error = ResponseContent {
1145            status: local_var_status,
1146            content: local_var_content,
1147            entity: local_var_entity,
1148            retry_delay: local_var_retry_delay,
1149        };
1150        Err(Error::ResponseError(local_var_error))
1151    }
1152}
1153
1154/// Restart an entire endpoint or a single component within an endpoint.
1155pub async fn restart_endpoint(
1156    configuration: &configuration::Configuration,
1157    endpoint_id: &str,
1158    restart_endpoint_request: Option<crate::models::RestartEndpointRequest>,
1159) -> Result<(), Error<RestartEndpointError>> {
1160    let mut backoff = configuration.backoff.clone();
1161    let mut refreshed_credentials = false;
1162    let method = reqwest::Method::POST;
1163    loop {
1164        let result = restart_endpoint_inner(
1165            configuration,
1166            &mut backoff,
1167            endpoint_id.clone(),
1168            restart_endpoint_request.clone(),
1169        )
1170        .await;
1171
1172        match result {
1173            Ok(result) => return Ok(result),
1174            Err(Error::ResponseError(response)) => {
1175                if !refreshed_credentials
1176                    && matches!(
1177                        response.status,
1178                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1179                    )
1180                {
1181                    configuration.qcs_config.refresh().await?;
1182                    refreshed_credentials = true;
1183                    continue;
1184                } else if let Some(duration) = response.retry_delay {
1185                    tokio::time::sleep(duration).await;
1186                    continue;
1187                }
1188
1189                return Err(Error::ResponseError(response));
1190            }
1191            Err(Error::Reqwest(error)) => {
1192                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1193                    tokio::time::sleep(duration).await;
1194                    continue;
1195                }
1196
1197                return Err(Error::Reqwest(error));
1198            }
1199            Err(Error::Io(error)) => {
1200                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1201                    tokio::time::sleep(duration).await;
1202                    continue;
1203                }
1204
1205                return Err(Error::Io(error));
1206            }
1207            Err(error) => return Err(error),
1208        }
1209    }
1210}