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    #[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    DefaultResponse(models::Error),
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    Status422(models::ValidationError),
202    DefaultResponse(models::Error),
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    Status422(models::ValidationError),
211    DefaultResponse(models::Error),
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 a v1 endpoint, releasing its resources. This operation is not reversible. Forwarded to Compute v1.
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/// 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
878pub async fn get_endpoint(
879    configuration: &configuration::Configuration,
880    endpoint_id: &str,
881) -> Result<models::Endpoint, Error<GetEndpointError>> {
882    let mut backoff = configuration.backoff.build();
883    let mut refreshed_credentials = false;
884    let method = reqwest::Method::GET;
885    loop {
886        let result = get_endpoint_inner(configuration, &mut backoff, endpoint_id.clone()).await;
887
888        match result {
889            Ok(result) => return Ok(result),
890            Err(Error::ResponseError(response)) => {
891                if !refreshed_credentials
892                    && matches!(
893                        response.status,
894                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
895                    )
896                {
897                    // Attempt to refresh credentials
898                    match configuration.qcs_config.refresh().await {
899                        Ok(_) => {
900                            refreshed_credentials = true;
901                            continue;
902                        }
903                        Err(::qcs_api_client_common::configuration::TokenError::Write {
904                            error,
905                            oauth_session: _,
906                        }) => {
907                            // Token refresh succeeded but persistence failed
908                            // The token is already in memory and will be used for this request
909                            #[cfg(feature = "tracing")]
910                            tracing::warn!(
911                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
912                                error
913                            );
914                            refreshed_credentials = true;
915                            continue;
916                        }
917                        Err(e) => return Err(e.into()),
918                    }
919                } else if let Some(duration) = response.retry_delay {
920                    tokio::time::sleep(duration).await;
921                    continue;
922                }
923
924                return Err(Error::ResponseError(response));
925            }
926            Err(Error::Reqwest(error)) => {
927                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
928                    tokio::time::sleep(duration).await;
929                    continue;
930                }
931
932                return Err(Error::Reqwest(error));
933            }
934            Err(Error::Io(error)) => {
935                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
936                    tokio::time::sleep(duration).await;
937                    continue;
938                }
939
940                return Err(Error::Io(error));
941            }
942            Err(error) => return Err(error),
943        }
944    }
945}
946async fn list_endpoints_inner(
947    configuration: &configuration::Configuration,
948    backoff: &mut ExponentialBackoff,
949    filter: Option<&str>,
950    page_size: Option<i64>,
951    page_token: Option<&str>,
952) -> Result<models::ListEndpointsResponse, Error<ListEndpointsError>> {
953    let local_var_configuration = configuration;
954    // add a prefix to parameters to efficiently prevent name collisions
955    let p_query_filter = filter;
956    let p_query_page_size = page_size;
957    let p_query_page_token = page_token;
958
959    let local_var_client = &local_var_configuration.client;
960
961    let local_var_uri_str = format!(
962        "{}/v1/endpoints",
963        local_var_configuration.qcs_config.api_url()
964    );
965    let mut local_var_req_builder =
966        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
967
968    #[cfg(feature = "tracing")]
969    {
970        // Ignore parsing errors if the URL is invalid for some reason.
971        // If it is invalid, it will turn up as an error later when actually making the request.
972        let local_var_do_tracing = local_var_uri_str
973            .parse::<::url::Url>()
974            .ok()
975            .is_none_or(|url| {
976                configuration
977                    .qcs_config
978                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
979            });
980
981        if local_var_do_tracing {
982            ::tracing::debug!(
983                url=%local_var_uri_str,
984                method="GET",
985                "making list_endpoints request",
986            );
987        }
988    }
989
990    if let Some(ref local_var_str) = p_query_filter {
991        local_var_req_builder =
992            local_var_req_builder.query(&[("filter", &local_var_str.to_string())]);
993    }
994    if let Some(ref local_var_str) = p_query_page_size {
995        local_var_req_builder =
996            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
997    }
998    if let Some(ref local_var_str) = p_query_page_token {
999        local_var_req_builder =
1000            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
1001    }
1002
1003    // Use the QCS Bearer token if a client OAuthSession is present,
1004    // but do not require one when the security schema says it is optional.
1005    {
1006        use qcs_api_client_common::configuration::TokenError;
1007
1008        #[allow(
1009            clippy::nonminimal_bool,
1010            clippy::eq_op,
1011            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1012        )]
1013        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1014
1015        let token = local_var_configuration
1016            .qcs_config
1017            .get_bearer_access_token()
1018            .await;
1019
1020        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1021            // the client is configured without any OAuthSession, but this call does not require one.
1022            #[cfg(feature = "tracing")]
1023            tracing::debug!(
1024                "No client credentials found, but this call does not require authentication."
1025            );
1026        } else {
1027            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1028        }
1029    }
1030
1031    let local_var_req = local_var_req_builder.build()?;
1032    let local_var_resp = local_var_client.execute(local_var_req).await?;
1033
1034    let local_var_status = local_var_resp.status();
1035    let local_var_raw_content_type = local_var_resp
1036        .headers()
1037        .get("content-type")
1038        .and_then(|v| v.to_str().ok())
1039        .unwrap_or("application/octet-stream")
1040        .to_string();
1041    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
1042
1043    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1044        let local_var_content = local_var_resp.text().await?;
1045        match local_var_content_type {
1046            ContentType::Json => serde_path_to_error::deserialize(
1047                &mut serde_json::Deserializer::from_str(&local_var_content),
1048            )
1049            .map_err(Error::from),
1050            ContentType::Text => Err(Error::InvalidContentType {
1051                content_type: local_var_raw_content_type,
1052                return_type: "models::ListEndpointsResponse",
1053            }),
1054            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
1055                content_type: unknown_type,
1056                return_type: "models::ListEndpointsResponse",
1057            }),
1058        }
1059    } else {
1060        let local_var_retry_delay =
1061            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1062        let local_var_content = local_var_resp.text().await?;
1063        let local_var_entity: Option<ListEndpointsError> =
1064            serde_json::from_str(&local_var_content).ok();
1065        let local_var_error = ResponseContent {
1066            status: local_var_status,
1067            content: local_var_content,
1068            entity: local_var_entity,
1069            retry_delay: local_var_retry_delay,
1070        };
1071        Err(Error::ResponseError(local_var_error))
1072    }
1073}
1074
1075/// List all endpoints, optionally filtering by attribute.
1076pub async fn list_endpoints(
1077    configuration: &configuration::Configuration,
1078    filter: Option<&str>,
1079    page_size: Option<i64>,
1080    page_token: Option<&str>,
1081) -> Result<models::ListEndpointsResponse, Error<ListEndpointsError>> {
1082    let mut backoff = configuration.backoff.build();
1083    let mut refreshed_credentials = false;
1084    let method = reqwest::Method::GET;
1085    loop {
1086        let result = list_endpoints_inner(
1087            configuration,
1088            &mut backoff,
1089            filter.clone(),
1090            page_size.clone(),
1091            page_token.clone(),
1092        )
1093        .await;
1094
1095        match result {
1096            Ok(result) => return Ok(result),
1097            Err(Error::ResponseError(response)) => {
1098                if !refreshed_credentials
1099                    && matches!(
1100                        response.status,
1101                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1102                    )
1103                {
1104                    // Attempt to refresh credentials
1105                    match configuration.qcs_config.refresh().await {
1106                        Ok(_) => {
1107                            refreshed_credentials = true;
1108                            continue;
1109                        }
1110                        Err(::qcs_api_client_common::configuration::TokenError::Write {
1111                            error,
1112                            oauth_session: _,
1113                        }) => {
1114                            // Token refresh succeeded but persistence failed
1115                            // The token is already in memory and will be used for this request
1116                            #[cfg(feature = "tracing")]
1117                            tracing::warn!(
1118                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
1119                                error
1120                            );
1121                            refreshed_credentials = true;
1122                            continue;
1123                        }
1124                        Err(e) => return Err(e.into()),
1125                    }
1126                } else if let Some(duration) = response.retry_delay {
1127                    tokio::time::sleep(duration).await;
1128                    continue;
1129                }
1130
1131                return Err(Error::ResponseError(response));
1132            }
1133            Err(Error::Reqwest(error)) => {
1134                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1135                    tokio::time::sleep(duration).await;
1136                    continue;
1137                }
1138
1139                return Err(Error::Reqwest(error));
1140            }
1141            Err(Error::Io(error)) => {
1142                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1143                    tokio::time::sleep(duration).await;
1144                    continue;
1145                }
1146
1147                return Err(Error::Io(error));
1148            }
1149            Err(error) => return Err(error),
1150        }
1151    }
1152}
1153async fn restart_endpoint_inner(
1154    configuration: &configuration::Configuration,
1155    backoff: &mut ExponentialBackoff,
1156    endpoint_id: &str,
1157    restart_endpoint_request: Option<crate::models::RestartEndpointRequest>,
1158) -> Result<(), Error<RestartEndpointError>> {
1159    let local_var_configuration = configuration;
1160    // add a prefix to parameters to efficiently prevent name collisions
1161    let p_path_endpoint_id = endpoint_id;
1162    let p_body_restart_endpoint_request = restart_endpoint_request;
1163
1164    let local_var_client = &local_var_configuration.client;
1165
1166    let local_var_uri_str = format!(
1167        "{}/v1/endpoints/{endpointId}:restart",
1168        local_var_configuration.qcs_config.api_url(),
1169        endpointId = crate::apis::urlencode(p_path_endpoint_id)
1170    );
1171    let mut local_var_req_builder =
1172        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
1173
1174    #[cfg(feature = "tracing")]
1175    {
1176        // Ignore parsing errors if the URL is invalid for some reason.
1177        // If it is invalid, it will turn up as an error later when actually making the request.
1178        let local_var_do_tracing = local_var_uri_str
1179            .parse::<::url::Url>()
1180            .ok()
1181            .is_none_or(|url| {
1182                configuration
1183                    .qcs_config
1184                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
1185            });
1186
1187        if local_var_do_tracing {
1188            ::tracing::debug!(
1189                url=%local_var_uri_str,
1190                method="POST",
1191                "making restart_endpoint request",
1192            );
1193        }
1194    }
1195
1196    // Use the QCS Bearer token if a client OAuthSession is present,
1197    // but do not require one when the security schema says it is optional.
1198    {
1199        use qcs_api_client_common::configuration::TokenError;
1200
1201        #[allow(
1202            clippy::nonminimal_bool,
1203            clippy::eq_op,
1204            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1205        )]
1206        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1207
1208        let token = local_var_configuration
1209            .qcs_config
1210            .get_bearer_access_token()
1211            .await;
1212
1213        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1214            // the client is configured without any OAuthSession, but this call does not require one.
1215            #[cfg(feature = "tracing")]
1216            tracing::debug!(
1217                "No client credentials found, but this call does not require authentication."
1218            );
1219        } else {
1220            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1221        }
1222    }
1223
1224    local_var_req_builder = local_var_req_builder.json(&p_body_restart_endpoint_request);
1225
1226    let local_var_req = local_var_req_builder.build()?;
1227    let local_var_resp = local_var_client.execute(local_var_req).await?;
1228
1229    let local_var_status = local_var_resp.status();
1230
1231    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1232        Ok(())
1233    } else {
1234        let local_var_retry_delay =
1235            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1236        let local_var_content = local_var_resp.text().await?;
1237        let local_var_entity: Option<RestartEndpointError> =
1238            serde_json::from_str(&local_var_content).ok();
1239        let local_var_error = ResponseContent {
1240            status: local_var_status,
1241            content: local_var_content,
1242            entity: local_var_entity,
1243            retry_delay: local_var_retry_delay,
1244        };
1245        Err(Error::ResponseError(local_var_error))
1246    }
1247}
1248
1249/// Restart an entire endpoint or a single component within an endpoint.
1250pub async fn restart_endpoint(
1251    configuration: &configuration::Configuration,
1252    endpoint_id: &str,
1253    restart_endpoint_request: Option<crate::models::RestartEndpointRequest>,
1254) -> Result<(), Error<RestartEndpointError>> {
1255    let mut backoff = configuration.backoff.build();
1256    let mut refreshed_credentials = false;
1257    let method = reqwest::Method::POST;
1258    loop {
1259        let result = restart_endpoint_inner(
1260            configuration,
1261            &mut backoff,
1262            endpoint_id.clone(),
1263            restart_endpoint_request.clone(),
1264        )
1265        .await;
1266
1267        match result {
1268            Ok(result) => return Ok(result),
1269            Err(Error::ResponseError(response)) => {
1270                if !refreshed_credentials
1271                    && matches!(
1272                        response.status,
1273                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1274                    )
1275                {
1276                    // Attempt to refresh credentials
1277                    match configuration.qcs_config.refresh().await {
1278                        Ok(_) => {
1279                            refreshed_credentials = true;
1280                            continue;
1281                        }
1282                        Err(::qcs_api_client_common::configuration::TokenError::Write {
1283                            error,
1284                            oauth_session: _,
1285                        }) => {
1286                            // Token refresh succeeded but persistence failed
1287                            // The token is already in memory and will be used for this request
1288                            #[cfg(feature = "tracing")]
1289                            tracing::warn!(
1290                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
1291                                error
1292                            );
1293                            refreshed_credentials = true;
1294                            continue;
1295                        }
1296                        Err(e) => return Err(e.into()),
1297                    }
1298                } else if let Some(duration) = response.retry_delay {
1299                    tokio::time::sleep(duration).await;
1300                    continue;
1301                }
1302
1303                return Err(Error::ResponseError(response));
1304            }
1305            Err(Error::Reqwest(error)) => {
1306                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1307                    tokio::time::sleep(duration).await;
1308                    continue;
1309                }
1310
1311                return Err(Error::Reqwest(error));
1312            }
1313            Err(Error::Io(error)) => {
1314                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1315                    tokio::time::sleep(duration).await;
1316                    continue;
1317                }
1318
1319                return Err(Error::Io(error));
1320            }
1321            Err(error) => return Err(error),
1322        }
1323    }
1324}