Skip to main content

qcs_api_client_openapi/apis/
endpoints_api.rs

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