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    ExponentialBackoff, duration_from_io_error, duration_from_reqwest_error, duration_from_response,
29};
30#[cfg(feature = "tracing")]
31use qcs_api_client_common::configuration::tokens::TokenRefresher;
32use qcs_dependencies_client::reqwest::{self, StatusCode};
33use serde::{Deserialize, Serialize};
34
35#[cfg(feature = "clap")]
36#[allow(unused, reason = "not used in all templates, but required in some")]
37use ::{miette::IntoDiagnostic as _, qcs_api_client_common::clap_utils::JsonMaybeStdin};
38
39/// Serialize command-line arguments for [`create_endpoint`]
40#[cfg(feature = "clap")]
41#[derive(Debug, clap::Args)]
42pub struct CreateEndpointClapParams {
43    pub create_endpoint_parameters: JsonMaybeStdin<crate::models::CreateEndpointParameters>,
44}
45
46#[cfg(feature = "clap")]
47impl CreateEndpointClapParams {
48    pub async fn execute(
49        self,
50        configuration: &configuration::Configuration,
51    ) -> Result<models::Endpoint, miette::Error> {
52        let request = self.create_endpoint_parameters.into_inner().into_inner();
53
54        create_endpoint(configuration, request)
55            .await
56            .into_diagnostic()
57    }
58}
59
60/// Serialize command-line arguments for [`delete_endpoint`]
61#[cfg(feature = "clap")]
62#[derive(Debug, clap::Args)]
63pub struct DeleteEndpointClapParams {
64    #[arg(long)]
65    pub endpoint_id: String,
66}
67
68#[cfg(feature = "clap")]
69impl DeleteEndpointClapParams {
70    pub async fn execute(
71        self,
72        configuration: &configuration::Configuration,
73    ) -> Result<(), miette::Error> {
74        delete_endpoint(configuration, self.endpoint_id.as_str())
75            .await
76            .into_diagnostic()
77    }
78}
79
80/// Serialize command-line arguments for [`get_default_endpoint`]
81#[cfg(feature = "clap")]
82#[derive(Debug, clap::Args)]
83pub struct GetDefaultEndpointClapParams {
84    /// Public identifier for a quantum processor [example: Aspen-1]
85    #[arg(long)]
86    pub quantum_processor_id: String,
87}
88
89#[cfg(feature = "clap")]
90impl GetDefaultEndpointClapParams {
91    pub async fn execute(
92        self,
93        configuration: &configuration::Configuration,
94    ) -> Result<models::Endpoint, miette::Error> {
95        get_default_endpoint(configuration, self.quantum_processor_id.as_str())
96            .await
97            .into_diagnostic()
98    }
99}
100
101/// Serialize command-line arguments for [`get_endpoint`]
102#[cfg(feature = "clap")]
103#[derive(Debug, clap::Args)]
104pub struct GetEndpointClapParams {
105    #[arg(long)]
106    pub endpoint_id: String,
107}
108
109#[cfg(feature = "clap")]
110impl GetEndpointClapParams {
111    pub async fn execute(
112        self,
113        configuration: &configuration::Configuration,
114    ) -> Result<models::Endpoint, miette::Error> {
115        get_endpoint(configuration, self.endpoint_id.as_str())
116            .await
117            .into_diagnostic()
118    }
119}
120
121/// Serialize command-line arguments for [`list_endpoints`]
122#[cfg(feature = "clap")]
123#[derive(Debug, clap::Args)]
124pub struct ListEndpointsClapParams {
125    /// Filtering logic specified using [rule-engine](https://zerosteiner.github.io/rule-engine/syntax.html) grammar
126    #[arg(long)]
127    pub filter: Option<String>,
128    #[arg(long)]
129    pub page_size: Option<i64>,
130    #[arg(long)]
131    pub page_token: Option<String>,
132}
133
134#[cfg(feature = "clap")]
135impl ListEndpointsClapParams {
136    pub async fn execute(
137        self,
138        configuration: &configuration::Configuration,
139    ) -> Result<models::ListEndpointsResponse, miette::Error> {
140        list_endpoints(
141            configuration,
142            self.filter.as_deref(),
143            self.page_size,
144            self.page_token.as_deref(),
145        )
146        .await
147        .into_diagnostic()
148    }
149}
150
151/// Serialize command-line arguments for [`restart_endpoint`]
152#[cfg(feature = "clap")]
153#[derive(Debug, clap::Args)]
154pub struct RestartEndpointClapParams {
155    #[arg(long)]
156    pub endpoint_id: String,
157    pub restart_endpoint_request: Option<JsonMaybeStdin<crate::models::RestartEndpointRequest>>,
158}
159
160#[cfg(feature = "clap")]
161impl RestartEndpointClapParams {
162    pub async fn execute(
163        self,
164        configuration: &configuration::Configuration,
165    ) -> Result<(), miette::Error> {
166        let request = self
167            .restart_endpoint_request
168            .map(|body| body.into_inner().into_inner());
169
170        restart_endpoint(configuration, self.endpoint_id.as_str(), request)
171            .await
172            .into_diagnostic()
173    }
174}
175
176/// struct for typed errors of method [`create_endpoint`]
177#[derive(Debug, Clone, Serialize, Deserialize)]
178#[serde(untagged)]
179pub enum CreateEndpointError {
180    Status400(models::Error),
181    Status404(models::Error),
182    Status422(models::ValidationError),
183    UnknownValue(serde_json::Value),
184}
185
186/// struct for typed errors of method [`delete_endpoint`]
187#[derive(Debug, Clone, Serialize, Deserialize)]
188#[serde(untagged)]
189pub enum DeleteEndpointError {
190    Status403(models::Error),
191    Status404(models::Error),
192    Status422(models::ValidationError),
193    UnknownValue(serde_json::Value),
194}
195
196/// struct for typed errors of method [`get_default_endpoint`]
197#[derive(Debug, Clone, Serialize, Deserialize)]
198#[serde(untagged)]
199pub enum GetDefaultEndpointError {
200    Status404(models::Error),
201    Status422(models::ValidationError),
202    UnknownValue(serde_json::Value),
203}
204
205/// struct for typed errors of method [`get_endpoint`]
206#[derive(Debug, Clone, Serialize, Deserialize)]
207#[serde(untagged)]
208pub enum GetEndpointError {
209    Status404(models::Error),
210    Status422(models::ValidationError),
211    UnknownValue(serde_json::Value),
212}
213
214/// struct for typed errors of method [`list_endpoints`]
215#[derive(Debug, Clone, Serialize, Deserialize)]
216#[serde(untagged)]
217pub enum ListEndpointsError {
218    Status422(models::ValidationError),
219    UnknownValue(serde_json::Value),
220}
221
222/// struct for typed errors of method [`restart_endpoint`]
223#[derive(Debug, Clone, Serialize, Deserialize)]
224#[serde(untagged)]
225pub enum RestartEndpointError {
226    Status403(models::Error),
227    Status422(models::ValidationError),
228    UnknownValue(serde_json::Value),
229}
230
231async fn create_endpoint_inner(
232    configuration: &configuration::Configuration,
233    backoff: &mut ExponentialBackoff,
234    create_endpoint_parameters: crate::models::CreateEndpointParameters,
235) -> Result<models::Endpoint, Error<CreateEndpointError>> {
236    let local_var_configuration = configuration;
237    // add a prefix to parameters to efficiently prevent name collisions
238    let p_body_create_endpoint_parameters = create_endpoint_parameters;
239
240    let local_var_client = &local_var_configuration.client;
241
242    let local_var_uri_str = format!(
243        "{}/v1/endpoints",
244        local_var_configuration.qcs_config.api_url()
245    );
246    let mut local_var_req_builder =
247        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
248
249    #[cfg(feature = "tracing")]
250    {
251        // Ignore parsing errors if the URL is invalid for some reason.
252        // If it is invalid, it will turn up as an error later when actually making the request.
253        let local_var_do_tracing = local_var_uri_str
254            .parse::<::url::Url>()
255            .ok()
256            .is_none_or(|url| {
257                configuration
258                    .qcs_config
259                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
260            });
261
262        if local_var_do_tracing {
263            ::tracing::debug!(
264                url=%local_var_uri_str,
265                method="POST",
266                "making create_endpoint request",
267            );
268        }
269    }
270
271    // Use the QCS Bearer token if a client OAuthSession is present,
272    // but do not require one when the security schema says it is optional.
273    {
274        use qcs_api_client_common::configuration::TokenError;
275
276        #[allow(
277            clippy::nonminimal_bool,
278            clippy::eq_op,
279            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
280        )]
281        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
282
283        let token = local_var_configuration
284            .qcs_config
285            .get_bearer_access_token()
286            .await;
287
288        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
289            // the client is configured without any OAuthSession, but this call does not require one.
290            #[cfg(feature = "tracing")]
291            tracing::debug!(
292                "No client credentials found, but this call does not require authentication."
293            );
294        } else {
295            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
296        }
297    }
298
299    local_var_req_builder = local_var_req_builder.json(&p_body_create_endpoint_parameters);
300
301    let local_var_req = local_var_req_builder.build()?;
302    let local_var_resp = local_var_client.execute(local_var_req).await?;
303
304    let local_var_status = local_var_resp.status();
305    let local_var_raw_content_type = local_var_resp
306        .headers()
307        .get("content-type")
308        .and_then(|v| v.to_str().ok())
309        .unwrap_or("application/octet-stream")
310        .to_string();
311    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
312
313    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
314        let local_var_content = local_var_resp.text().await?;
315        match local_var_content_type {
316            ContentType::Json => serde_path_to_error::deserialize(
317                &mut serde_json::Deserializer::from_str(&local_var_content),
318            )
319            .map_err(Error::from),
320            ContentType::Text => Err(Error::InvalidContentType {
321                content_type: local_var_raw_content_type,
322                return_type: "models::Endpoint",
323            }),
324            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
325                content_type: unknown_type,
326                return_type: "models::Endpoint",
327            }),
328        }
329    } else {
330        let local_var_retry_delay =
331            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
332        let local_var_content = local_var_resp.text().await?;
333        let local_var_entity: Option<CreateEndpointError> =
334            serde_json::from_str(&local_var_content).ok();
335        let local_var_error = ResponseContent {
336            status: local_var_status,
337            content: local_var_content,
338            entity: local_var_entity,
339            retry_delay: local_var_retry_delay,
340        };
341        Err(Error::ResponseError(local_var_error))
342    }
343}
344
345/// Create an endpoint associated with your user account.
346pub async fn create_endpoint(
347    configuration: &configuration::Configuration,
348    create_endpoint_parameters: crate::models::CreateEndpointParameters,
349) -> Result<models::Endpoint, Error<CreateEndpointError>> {
350    let mut backoff = configuration.backoff.clone();
351    let mut refreshed_credentials = false;
352    let method = reqwest::Method::POST;
353    loop {
354        let result = create_endpoint_inner(
355            configuration,
356            &mut backoff,
357            create_endpoint_parameters.clone(),
358        )
359        .await;
360
361        match result {
362            Ok(result) => return Ok(result),
363            Err(Error::ResponseError(response)) => {
364                if !refreshed_credentials
365                    && matches!(
366                        response.status,
367                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
368                    )
369                {
370                    // Attempt to refresh credentials
371                    match configuration.qcs_config.refresh().await {
372                        Ok(_) => {
373                            refreshed_credentials = true;
374                            continue;
375                        }
376                        Err(::qcs_api_client_common::configuration::TokenError::Write {
377                            error,
378                            oauth_session: _,
379                        }) => {
380                            // Token refresh succeeded but persistence failed
381                            // The token is already in memory and will be used for this request
382                            #[cfg(feature = "tracing")]
383                            tracing::warn!(
384                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
385                                error
386                            );
387                            refreshed_credentials = true;
388                            continue;
389                        }
390                        Err(e) => return Err(e.into()),
391                    }
392                } else if let Some(duration) = response.retry_delay {
393                    tokio::time::sleep(duration).await;
394                    continue;
395                }
396
397                return Err(Error::ResponseError(response));
398            }
399            Err(Error::Reqwest(error)) => {
400                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
401                    tokio::time::sleep(duration).await;
402                    continue;
403                }
404
405                return Err(Error::Reqwest(error));
406            }
407            Err(Error::Io(error)) => {
408                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
409                    tokio::time::sleep(duration).await;
410                    continue;
411                }
412
413                return Err(Error::Io(error));
414            }
415            Err(error) => return Err(error),
416        }
417    }
418}
419async fn delete_endpoint_inner(
420    configuration: &configuration::Configuration,
421    backoff: &mut ExponentialBackoff,
422    endpoint_id: &str,
423) -> Result<(), Error<DeleteEndpointError>> {
424    let local_var_configuration = configuration;
425    // add a prefix to parameters to efficiently prevent name collisions
426    let p_path_endpoint_id = endpoint_id;
427
428    let local_var_client = &local_var_configuration.client;
429
430    let local_var_uri_str = format!(
431        "{}/v1/endpoints/{endpointId}",
432        local_var_configuration.qcs_config.api_url(),
433        endpointId = crate::apis::urlencode(p_path_endpoint_id)
434    );
435    let mut local_var_req_builder =
436        local_var_client.request(reqwest::Method::DELETE, local_var_uri_str.as_str());
437
438    #[cfg(feature = "tracing")]
439    {
440        // Ignore parsing errors if the URL is invalid for some reason.
441        // If it is invalid, it will turn up as an error later when actually making the request.
442        let local_var_do_tracing = local_var_uri_str
443            .parse::<::url::Url>()
444            .ok()
445            .is_none_or(|url| {
446                configuration
447                    .qcs_config
448                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
449            });
450
451        if local_var_do_tracing {
452            ::tracing::debug!(
453                url=%local_var_uri_str,
454                method="DELETE",
455                "making delete_endpoint request",
456            );
457        }
458    }
459
460    // Use the QCS Bearer token if a client OAuthSession is present,
461    // but do not require one when the security schema says it is optional.
462    {
463        use qcs_api_client_common::configuration::TokenError;
464
465        #[allow(
466            clippy::nonminimal_bool,
467            clippy::eq_op,
468            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
469        )]
470        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
471
472        let token = local_var_configuration
473            .qcs_config
474            .get_bearer_access_token()
475            .await;
476
477        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
478            // the client is configured without any OAuthSession, but this call does not require one.
479            #[cfg(feature = "tracing")]
480            tracing::debug!(
481                "No client credentials found, but this call does not require authentication."
482            );
483        } else {
484            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
485        }
486    }
487
488    let local_var_req = local_var_req_builder.build()?;
489    let local_var_resp = local_var_client.execute(local_var_req).await?;
490
491    let local_var_status = local_var_resp.status();
492
493    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
494        Ok(())
495    } else {
496        let local_var_retry_delay =
497            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
498        let local_var_content = local_var_resp.text().await?;
499        let local_var_entity: Option<DeleteEndpointError> =
500            serde_json::from_str(&local_var_content).ok();
501        let local_var_error = ResponseContent {
502            status: local_var_status,
503            content: local_var_content,
504            entity: local_var_entity,
505            retry_delay: local_var_retry_delay,
506        };
507        Err(Error::ResponseError(local_var_error))
508    }
509}
510
511/// Delete an endpoint, releasing its resources. This operation is not reversible.
512pub async fn delete_endpoint(
513    configuration: &configuration::Configuration,
514    endpoint_id: &str,
515) -> Result<(), Error<DeleteEndpointError>> {
516    let mut backoff = configuration.backoff.clone();
517    let mut refreshed_credentials = false;
518    let method = reqwest::Method::DELETE;
519    loop {
520        let result = delete_endpoint_inner(configuration, &mut backoff, endpoint_id.clone()).await;
521
522        match result {
523            Ok(result) => return Ok(result),
524            Err(Error::ResponseError(response)) => {
525                if !refreshed_credentials
526                    && matches!(
527                        response.status,
528                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
529                    )
530                {
531                    // Attempt to refresh credentials
532                    match configuration.qcs_config.refresh().await {
533                        Ok(_) => {
534                            refreshed_credentials = true;
535                            continue;
536                        }
537                        Err(::qcs_api_client_common::configuration::TokenError::Write {
538                            error,
539                            oauth_session: _,
540                        }) => {
541                            // Token refresh succeeded but persistence failed
542                            // The token is already in memory and will be used for this request
543                            #[cfg(feature = "tracing")]
544                            tracing::warn!(
545                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
546                                error
547                            );
548                            refreshed_credentials = true;
549                            continue;
550                        }
551                        Err(e) => return Err(e.into()),
552                    }
553                } else if let Some(duration) = response.retry_delay {
554                    tokio::time::sleep(duration).await;
555                    continue;
556                }
557
558                return Err(Error::ResponseError(response));
559            }
560            Err(Error::Reqwest(error)) => {
561                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
562                    tokio::time::sleep(duration).await;
563                    continue;
564                }
565
566                return Err(Error::Reqwest(error));
567            }
568            Err(Error::Io(error)) => {
569                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
570                    tokio::time::sleep(duration).await;
571                    continue;
572                }
573
574                return Err(Error::Io(error));
575            }
576            Err(error) => return Err(error),
577        }
578    }
579}
580async fn get_default_endpoint_inner(
581    configuration: &configuration::Configuration,
582    backoff: &mut ExponentialBackoff,
583    quantum_processor_id: &str,
584) -> Result<models::Endpoint, Error<GetDefaultEndpointError>> {
585    let local_var_configuration = configuration;
586    // add a prefix to parameters to efficiently prevent name collisions
587    let p_path_quantum_processor_id = quantum_processor_id;
588
589    let local_var_client = &local_var_configuration.client;
590
591    let local_var_uri_str = format!(
592        "{}/v1/quantumProcessors/{quantumProcessorId}/endpoints:getDefault",
593        local_var_configuration.qcs_config.api_url(),
594        quantumProcessorId = crate::apis::urlencode(p_path_quantum_processor_id)
595    );
596    let mut local_var_req_builder =
597        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
598
599    #[cfg(feature = "tracing")]
600    {
601        // Ignore parsing errors if the URL is invalid for some reason.
602        // If it is invalid, it will turn up as an error later when actually making the request.
603        let local_var_do_tracing = local_var_uri_str
604            .parse::<::url::Url>()
605            .ok()
606            .is_none_or(|url| {
607                configuration
608                    .qcs_config
609                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
610            });
611
612        if local_var_do_tracing {
613            ::tracing::debug!(
614                url=%local_var_uri_str,
615                method="GET",
616                "making get_default_endpoint request",
617            );
618        }
619    }
620
621    // Use the QCS Bearer token if a client OAuthSession is present,
622    // but do not require one when the security schema says it is optional.
623    {
624        use qcs_api_client_common::configuration::TokenError;
625
626        #[allow(
627            clippy::nonminimal_bool,
628            clippy::eq_op,
629            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
630        )]
631        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
632
633        let token = local_var_configuration
634            .qcs_config
635            .get_bearer_access_token()
636            .await;
637
638        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
639            // the client is configured without any OAuthSession, but this call does not require one.
640            #[cfg(feature = "tracing")]
641            tracing::debug!(
642                "No client credentials found, but this call does not require authentication."
643            );
644        } else {
645            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
646        }
647    }
648
649    let local_var_req = local_var_req_builder.build()?;
650    let local_var_resp = local_var_client.execute(local_var_req).await?;
651
652    let local_var_status = local_var_resp.status();
653    let local_var_raw_content_type = local_var_resp
654        .headers()
655        .get("content-type")
656        .and_then(|v| v.to_str().ok())
657        .unwrap_or("application/octet-stream")
658        .to_string();
659    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
660
661    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
662        let local_var_content = local_var_resp.text().await?;
663        match local_var_content_type {
664            ContentType::Json => serde_path_to_error::deserialize(
665                &mut serde_json::Deserializer::from_str(&local_var_content),
666            )
667            .map_err(Error::from),
668            ContentType::Text => Err(Error::InvalidContentType {
669                content_type: local_var_raw_content_type,
670                return_type: "models::Endpoint",
671            }),
672            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
673                content_type: unknown_type,
674                return_type: "models::Endpoint",
675            }),
676        }
677    } else {
678        let local_var_retry_delay =
679            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
680        let local_var_content = local_var_resp.text().await?;
681        let local_var_entity: Option<GetDefaultEndpointError> =
682            serde_json::from_str(&local_var_content).ok();
683        let local_var_error = ResponseContent {
684            status: local_var_status,
685            content: local_var_content,
686            entity: local_var_entity,
687            retry_delay: local_var_retry_delay,
688        };
689        Err(Error::ResponseError(local_var_error))
690    }
691}
692
693/// Retrieve the endpoint set as \"default\" for the given Quantum Processor.  If no endpoint is set as the default, return \"not found.\"
694pub async fn get_default_endpoint(
695    configuration: &configuration::Configuration,
696    quantum_processor_id: &str,
697) -> Result<models::Endpoint, Error<GetDefaultEndpointError>> {
698    let mut backoff = configuration.backoff.clone();
699    let mut refreshed_credentials = false;
700    let method = reqwest::Method::GET;
701    loop {
702        let result =
703            get_default_endpoint_inner(configuration, &mut backoff, quantum_processor_id.clone())
704                .await;
705
706        match result {
707            Ok(result) => return Ok(result),
708            Err(Error::ResponseError(response)) => {
709                if !refreshed_credentials
710                    && matches!(
711                        response.status,
712                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
713                    )
714                {
715                    // Attempt to refresh credentials
716                    match configuration.qcs_config.refresh().await {
717                        Ok(_) => {
718                            refreshed_credentials = true;
719                            continue;
720                        }
721                        Err(::qcs_api_client_common::configuration::TokenError::Write {
722                            error,
723                            oauth_session: _,
724                        }) => {
725                            // Token refresh succeeded but persistence failed
726                            // The token is already in memory and will be used for this request
727                            #[cfg(feature = "tracing")]
728                            tracing::warn!(
729                                "Token refresh succeeded but failed to persist: {}. Continuing with in-memory token.",
730                                error
731                            );
732                            refreshed_credentials = true;
733                            continue;
734                        }
735                        Err(e) => return Err(e.into()),
736                    }
737                } else if let Some(duration) = response.retry_delay {
738                    tokio::time::sleep(duration).await;
739                    continue;
740                }
741
742                return Err(Error::ResponseError(response));
743            }
744            Err(Error::Reqwest(error)) => {
745                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
746                    tokio::time::sleep(duration).await;
747                    continue;
748                }
749
750                return Err(Error::Reqwest(error));
751            }
752            Err(Error::Io(error)) => {
753                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
754                    tokio::time::sleep(duration).await;
755                    continue;
756                }
757
758                return Err(Error::Io(error));
759            }
760            Err(error) => return Err(error),
761        }
762    }
763}
764async fn get_endpoint_inner(
765    configuration: &configuration::Configuration,
766    backoff: &mut ExponentialBackoff,
767    endpoint_id: &str,
768) -> Result<models::Endpoint, Error<GetEndpointError>> {
769    let local_var_configuration = configuration;
770    // add a prefix to parameters to efficiently prevent name collisions
771    let p_path_endpoint_id = endpoint_id;
772
773    let local_var_client = &local_var_configuration.client;
774
775    let local_var_uri_str = format!(
776        "{}/v1/endpoints/{endpointId}",
777        local_var_configuration.qcs_config.api_url(),
778        endpointId = crate::apis::urlencode(p_path_endpoint_id)
779    );
780    let mut local_var_req_builder =
781        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
782
783    #[cfg(feature = "tracing")]
784    {
785        // Ignore parsing errors if the URL is invalid for some reason.
786        // If it is invalid, it will turn up as an error later when actually making the request.
787        let local_var_do_tracing = local_var_uri_str
788            .parse::<::url::Url>()
789            .ok()
790            .is_none_or(|url| {
791                configuration
792                    .qcs_config
793                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
794            });
795
796        if local_var_do_tracing {
797            ::tracing::debug!(
798                url=%local_var_uri_str,
799                method="GET",
800                "making get_endpoint request",
801            );
802        }
803    }
804
805    // Use the QCS Bearer token if a client OAuthSession is present,
806    // but do not require one when the security schema says it is optional.
807    {
808        use qcs_api_client_common::configuration::TokenError;
809
810        #[allow(
811            clippy::nonminimal_bool,
812            clippy::eq_op,
813            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
814        )]
815        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
816
817        let token = local_var_configuration
818            .qcs_config
819            .get_bearer_access_token()
820            .await;
821
822        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
823            // the client is configured without any OAuthSession, but this call does not require one.
824            #[cfg(feature = "tracing")]
825            tracing::debug!(
826                "No client credentials found, but this call does not require authentication."
827            );
828        } else {
829            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
830        }
831    }
832
833    let local_var_req = local_var_req_builder.build()?;
834    let local_var_resp = local_var_client.execute(local_var_req).await?;
835
836    let local_var_status = local_var_resp.status();
837    let local_var_raw_content_type = local_var_resp
838        .headers()
839        .get("content-type")
840        .and_then(|v| v.to_str().ok())
841        .unwrap_or("application/octet-stream")
842        .to_string();
843    let local_var_content_type = super::ContentType::from(local_var_raw_content_type.as_str());
844
845    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
846        let local_var_content = local_var_resp.text().await?;
847        match local_var_content_type {
848            ContentType::Json => serde_path_to_error::deserialize(
849                &mut serde_json::Deserializer::from_str(&local_var_content),
850            )
851            .map_err(Error::from),
852            ContentType::Text => Err(Error::InvalidContentType {
853                content_type: local_var_raw_content_type,
854                return_type: "models::Endpoint",
855            }),
856            ContentType::Unsupported(unknown_type) => Err(Error::InvalidContentType {
857                content_type: unknown_type,
858                return_type: "models::Endpoint",
859            }),
860        }
861    } else {
862        let local_var_retry_delay =
863            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
864        let local_var_content = local_var_resp.text().await?;
865        let local_var_entity: Option<GetEndpointError> =
866            serde_json::from_str(&local_var_content).ok();
867        let local_var_error = ResponseContent {
868            status: local_var_status,
869            content: local_var_content,
870            entity: local_var_entity,
871            retry_delay: local_var_retry_delay,
872        };
873        Err(Error::ResponseError(local_var_error))
874    }
875}
876
877/// Retrieve a specific endpoint by its ID.
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.clone();
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.clone();
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.clone();
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}