qcs_api_client_openapi/apis/
endpoints_api.rs

1// Copyright 2022 Rigetti Computing
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*
16 * Rigetti QCS API
17 *
18 * # Introduction  This is the documentation for the Rigetti QCS HTTP API.  You can find out more about Rigetti at [https://rigetti.com](https://rigetti.com), and also interact with QCS via the web at [https://qcs.rigetti.com](https://qcs.rigetti.com).  This API is documented in **OpenAPI format** and so is compatible with the dozens of language-specific client generators available [here](https://github.com/OpenAPITools/openapi-generator) and elsewhere on the web.  # Principles  This API follows REST design principles where appropriate, and otherwise an HTTP RPC paradigm. We adhere to the Google [API Improvement Proposals](https://google.aip.dev/general) where reasonable to provide a consistent, intuitive developer experience. HTTP response codes match their specifications, and error messages fit a common format.  # Authentication  All access to the QCS API requires OAuth2 authentication provided by Okta. You can request access [here](https://www.rigetti.com/get-quantum). Once you have a user account, you can download your access token from QCS [here](https://qcs.rigetti.com/auth/token).   That access token is valid for 24 hours after issuance. The value of `access_token` within the JSON file is the token used for authentication (don't use the entire JSON file).  Authenticate requests using the `Authorization` header and a `Bearer` prefix:  ``` curl --header \"Authorization: Bearer eyJraW...Iow\" ```  # Quantum Processor Access  Access to the quantum processors themselves is not yet provided directly by this HTTP API, but is instead performed over ZeroMQ/[rpcq](https://github.com/rigetti/rpcq). Until that changes, we suggest using [pyquil](https://github.com/rigetti/pyquil) to build and execute quantum programs via the Legacy API.  # Legacy API  Our legacy HTTP API remains accessible at https://forest-server.qcs.rigetti.com, and it shares a source of truth with this API's services. You can use either service with the same user account and means of authentication. We strongly recommend using the API documented here, as the legacy API is on the path to deprecation.
19 *
20 * The version of the OpenAPI document: 2020-07-31
21 * Contact: support@rigetti.com
22 * Generated by: https://openapi-generator.tech
23 */
24
25use super::{configuration, Error};
26use crate::apis::ResponseContent;
27use ::qcs_api_client_common::backoff::{
28    duration_from_io_error, duration_from_reqwest_error, duration_from_response, ExponentialBackoff,
29};
30#[cfg(feature = "tracing")]
31use qcs_api_client_common::configuration::tokens::TokenRefresher;
32use reqwest::StatusCode;
33use serde::{Deserialize, Serialize};
34
35/// Serialize command-line arguments for [`create_endpoint`]
36#[cfg(feature = "clap")]
37#[derive(Debug, clap::Args)]
38pub struct CreateEndpointClapParams {
39    pub create_endpoint_parameters:
40        crate::clap_utils::JsonMaybeStdin<crate::models::CreateEndpointParameters>,
41}
42
43#[cfg(feature = "clap")]
44impl CreateEndpointClapParams {
45    pub async fn execute(
46        self,
47        configuration: &configuration::Configuration,
48    ) -> Result<crate::models::Endpoint, anyhow::Error> {
49        let request = self.create_endpoint_parameters.into_inner().into_inner();
50
51        create_endpoint(configuration, request)
52            .await
53            .map_err(Into::into)
54    }
55}
56
57/// Serialize command-line arguments for [`delete_endpoint`]
58#[cfg(feature = "clap")]
59#[derive(Debug, clap::Args)]
60pub struct DeleteEndpointClapParams {
61    #[arg(long)]
62    pub endpoint_id: String,
63}
64
65#[cfg(feature = "clap")]
66impl DeleteEndpointClapParams {
67    pub async fn execute(
68        self,
69        configuration: &configuration::Configuration,
70    ) -> Result<(), anyhow::Error> {
71        delete_endpoint(configuration, self.endpoint_id.as_str())
72            .await
73            .map_err(Into::into)
74    }
75}
76
77/// Serialize command-line arguments for [`get_default_endpoint`]
78#[cfg(feature = "clap")]
79#[derive(Debug, clap::Args)]
80pub struct GetDefaultEndpointClapParams {
81    /// Public identifier for a quantum processor [example: Aspen-1]
82    #[arg(long)]
83    pub quantum_processor_id: String,
84}
85
86#[cfg(feature = "clap")]
87impl GetDefaultEndpointClapParams {
88    pub async fn execute(
89        self,
90        configuration: &configuration::Configuration,
91    ) -> Result<crate::models::Endpoint, anyhow::Error> {
92        get_default_endpoint(configuration, self.quantum_processor_id.as_str())
93            .await
94            .map_err(Into::into)
95    }
96}
97
98/// Serialize command-line arguments for [`get_endpoint`]
99#[cfg(feature = "clap")]
100#[derive(Debug, clap::Args)]
101pub struct GetEndpointClapParams {
102    #[arg(long)]
103    pub endpoint_id: String,
104}
105
106#[cfg(feature = "clap")]
107impl GetEndpointClapParams {
108    pub async fn execute(
109        self,
110        configuration: &configuration::Configuration,
111    ) -> Result<crate::models::Endpoint, anyhow::Error> {
112        get_endpoint(configuration, self.endpoint_id.as_str())
113            .await
114            .map_err(Into::into)
115    }
116}
117
118/// Serialize command-line arguments for [`list_endpoints`]
119#[cfg(feature = "clap")]
120#[derive(Debug, clap::Args)]
121pub struct ListEndpointsClapParams {
122    /// Filtering logic specified using [rule-engine](https://zerosteiner.github.io/rule-engine/syntax.html) grammar
123    #[arg(long)]
124    pub filter: Option<String>,
125    #[arg(long)]
126    pub page_size: Option<i64>,
127    #[arg(long)]
128    pub page_token: Option<String>,
129}
130
131#[cfg(feature = "clap")]
132impl ListEndpointsClapParams {
133    pub async fn execute(
134        self,
135        configuration: &configuration::Configuration,
136    ) -> Result<crate::models::ListEndpointsResponse, anyhow::Error> {
137        list_endpoints(
138            configuration,
139            self.filter.as_deref(),
140            self.page_size,
141            self.page_token.as_deref(),
142        )
143        .await
144        .map_err(Into::into)
145    }
146}
147
148/// Serialize command-line arguments for [`restart_endpoint`]
149#[cfg(feature = "clap")]
150#[derive(Debug, clap::Args)]
151pub struct RestartEndpointClapParams {
152    #[arg(long)]
153    pub endpoint_id: String,
154    pub restart_endpoint_request:
155        Option<crate::clap_utils::JsonMaybeStdin<crate::models::RestartEndpointRequest>>,
156}
157
158#[cfg(feature = "clap")]
159impl RestartEndpointClapParams {
160    pub async fn execute(
161        self,
162        configuration: &configuration::Configuration,
163    ) -> Result<(), anyhow::Error> {
164        let request = self
165            .restart_endpoint_request
166            .map(|body| body.into_inner().into_inner());
167
168        restart_endpoint(configuration, self.endpoint_id.as_str(), request)
169            .await
170            .map_err(Into::into)
171    }
172}
173
174/// struct for typed errors of method [`create_endpoint`]
175#[derive(Debug, Clone, Serialize, Deserialize)]
176#[serde(untagged)]
177pub enum CreateEndpointError {
178    Status400(crate::models::Error),
179    Status404(crate::models::Error),
180    Status422(crate::models::ValidationError),
181    UnknownValue(serde_json::Value),
182}
183
184/// struct for typed errors of method [`delete_endpoint`]
185#[derive(Debug, Clone, Serialize, Deserialize)]
186#[serde(untagged)]
187pub enum DeleteEndpointError {
188    Status403(crate::models::Error),
189    Status404(crate::models::Error),
190    Status422(crate::models::ValidationError),
191    UnknownValue(serde_json::Value),
192}
193
194/// struct for typed errors of method [`get_default_endpoint`]
195#[derive(Debug, Clone, Serialize, Deserialize)]
196#[serde(untagged)]
197pub enum GetDefaultEndpointError {
198    Status404(crate::models::Error),
199    Status422(crate::models::ValidationError),
200    UnknownValue(serde_json::Value),
201}
202
203/// struct for typed errors of method [`get_endpoint`]
204#[derive(Debug, Clone, Serialize, Deserialize)]
205#[serde(untagged)]
206pub enum GetEndpointError {
207    Status404(crate::models::Error),
208    Status422(crate::models::ValidationError),
209    UnknownValue(serde_json::Value),
210}
211
212/// struct for typed errors of method [`list_endpoints`]
213#[derive(Debug, Clone, Serialize, Deserialize)]
214#[serde(untagged)]
215pub enum ListEndpointsError {
216    Status422(crate::models::ValidationError),
217    UnknownValue(serde_json::Value),
218}
219
220/// struct for typed errors of method [`restart_endpoint`]
221#[derive(Debug, Clone, Serialize, Deserialize)]
222#[serde(untagged)]
223pub enum RestartEndpointError {
224    Status403(crate::models::Error),
225    Status422(crate::models::ValidationError),
226    UnknownValue(serde_json::Value),
227}
228
229async fn create_endpoint_inner(
230    configuration: &configuration::Configuration,
231    backoff: &mut ExponentialBackoff,
232    create_endpoint_parameters: crate::models::CreateEndpointParameters,
233) -> Result<crate::models::Endpoint, Error<CreateEndpointError>> {
234    let local_var_configuration = configuration;
235
236    let local_var_client = &local_var_configuration.client;
237
238    let local_var_uri_str = format!(
239        "{}/v1/endpoints",
240        local_var_configuration.qcs_config.api_url()
241    );
242    let mut local_var_req_builder =
243        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
244
245    #[cfg(feature = "tracing")]
246    {
247        // Ignore parsing errors if the URL is invalid for some reason.
248        // If it is invalid, it will turn up as an error later when actually making the request.
249        let local_var_do_tracing = local_var_uri_str
250            .parse::<::url::Url>()
251            .ok()
252            .is_none_or(|url| {
253                configuration
254                    .qcs_config
255                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
256            });
257
258        if local_var_do_tracing {
259            ::tracing::debug!(
260                url=%local_var_uri_str,
261                method="POST",
262                "making create_endpoint request",
263            );
264        }
265    }
266
267    // Use the QCS Bearer token if a client OAuthSession is present,
268    // but do not require one when the security schema says it is optional.
269    {
270        use qcs_api_client_common::configuration::TokenError;
271
272        #[allow(
273            clippy::nonminimal_bool,
274            clippy::eq_op,
275            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
276        )]
277        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
278
279        let token = local_var_configuration
280            .qcs_config
281            .get_bearer_access_token()
282            .await;
283
284        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
285            // the client is configured without any OAuthSession, but this call does not require one.
286            #[cfg(feature = "tracing")]
287            tracing::debug!(
288                "No client credentials found, but this call does not require authentication."
289            );
290        } else {
291            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
292        }
293    }
294
295    local_var_req_builder = local_var_req_builder.json(&create_endpoint_parameters);
296
297    let local_var_req = local_var_req_builder.build()?;
298    let local_var_resp = local_var_client.execute(local_var_req).await?;
299
300    let local_var_status = local_var_resp.status();
301
302    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
303        let local_var_content = local_var_resp.text().await?;
304        serde_json::from_str(&local_var_content).map_err(Error::from)
305    } else {
306        let local_var_retry_delay =
307            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
308        let local_var_content = local_var_resp.text().await?;
309        let local_var_entity: Option<CreateEndpointError> =
310            serde_json::from_str(&local_var_content).ok();
311        let local_var_error = ResponseContent {
312            status: local_var_status,
313            content: local_var_content,
314            entity: local_var_entity,
315            retry_delay: local_var_retry_delay,
316        };
317        Err(Error::ResponseError(local_var_error))
318    }
319}
320
321/// Create an endpoint associated with your user account.
322pub async fn create_endpoint(
323    configuration: &configuration::Configuration,
324    create_endpoint_parameters: crate::models::CreateEndpointParameters,
325) -> Result<crate::models::Endpoint, Error<CreateEndpointError>> {
326    let mut backoff = configuration.backoff.clone();
327    let mut refreshed_credentials = false;
328    let method = reqwest::Method::POST;
329    loop {
330        let result = create_endpoint_inner(
331            configuration,
332            &mut backoff,
333            create_endpoint_parameters.clone(),
334        )
335        .await;
336
337        match result {
338            Ok(result) => return Ok(result),
339            Err(Error::ResponseError(response)) => {
340                if !refreshed_credentials
341                    && matches!(
342                        response.status,
343                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
344                    )
345                {
346                    configuration.qcs_config.refresh().await?;
347                    refreshed_credentials = true;
348                    continue;
349                } else if let Some(duration) = response.retry_delay {
350                    tokio::time::sleep(duration).await;
351                    continue;
352                }
353
354                return Err(Error::ResponseError(response));
355            }
356            Err(Error::Reqwest(error)) => {
357                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
358                    tokio::time::sleep(duration).await;
359                    continue;
360                }
361
362                return Err(Error::Reqwest(error));
363            }
364            Err(Error::Io(error)) => {
365                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
366                    tokio::time::sleep(duration).await;
367                    continue;
368                }
369
370                return Err(Error::Io(error));
371            }
372            Err(error) => return Err(error),
373        }
374    }
375}
376async fn delete_endpoint_inner(
377    configuration: &configuration::Configuration,
378    backoff: &mut ExponentialBackoff,
379    endpoint_id: &str,
380) -> Result<(), Error<DeleteEndpointError>> {
381    let local_var_configuration = configuration;
382
383    let local_var_client = &local_var_configuration.client;
384
385    let local_var_uri_str = format!(
386        "{}/v1/endpoints/{endpointId}",
387        local_var_configuration.qcs_config.api_url(),
388        endpointId = crate::apis::urlencode(endpoint_id)
389    );
390    let mut local_var_req_builder =
391        local_var_client.request(reqwest::Method::DELETE, local_var_uri_str.as_str());
392
393    #[cfg(feature = "tracing")]
394    {
395        // Ignore parsing errors if the URL is invalid for some reason.
396        // If it is invalid, it will turn up as an error later when actually making the request.
397        let local_var_do_tracing = local_var_uri_str
398            .parse::<::url::Url>()
399            .ok()
400            .is_none_or(|url| {
401                configuration
402                    .qcs_config
403                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
404            });
405
406        if local_var_do_tracing {
407            ::tracing::debug!(
408                url=%local_var_uri_str,
409                method="DELETE",
410                "making delete_endpoint request",
411            );
412        }
413    }
414
415    // Use the QCS Bearer token if a client OAuthSession is present,
416    // but do not require one when the security schema says it is optional.
417    {
418        use qcs_api_client_common::configuration::TokenError;
419
420        #[allow(
421            clippy::nonminimal_bool,
422            clippy::eq_op,
423            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
424        )]
425        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
426
427        let token = local_var_configuration
428            .qcs_config
429            .get_bearer_access_token()
430            .await;
431
432        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
433            // the client is configured without any OAuthSession, but this call does not require one.
434            #[cfg(feature = "tracing")]
435            tracing::debug!(
436                "No client credentials found, but this call does not require authentication."
437            );
438        } else {
439            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
440        }
441    }
442
443    let local_var_req = local_var_req_builder.build()?;
444    let local_var_resp = local_var_client.execute(local_var_req).await?;
445
446    let local_var_status = local_var_resp.status();
447
448    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
449        Ok(())
450    } else {
451        let local_var_retry_delay =
452            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
453        let local_var_content = local_var_resp.text().await?;
454        let local_var_entity: Option<DeleteEndpointError> =
455            serde_json::from_str(&local_var_content).ok();
456        let local_var_error = ResponseContent {
457            status: local_var_status,
458            content: local_var_content,
459            entity: local_var_entity,
460            retry_delay: local_var_retry_delay,
461        };
462        Err(Error::ResponseError(local_var_error))
463    }
464}
465
466/// Delete an endpoint, releasing its resources. This operation is not reversible.
467pub async fn delete_endpoint(
468    configuration: &configuration::Configuration,
469    endpoint_id: &str,
470) -> Result<(), Error<DeleteEndpointError>> {
471    let mut backoff = configuration.backoff.clone();
472    let mut refreshed_credentials = false;
473    let method = reqwest::Method::DELETE;
474    loop {
475        let result = delete_endpoint_inner(configuration, &mut backoff, endpoint_id.clone()).await;
476
477        match result {
478            Ok(result) => return Ok(result),
479            Err(Error::ResponseError(response)) => {
480                if !refreshed_credentials
481                    && matches!(
482                        response.status,
483                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
484                    )
485                {
486                    configuration.qcs_config.refresh().await?;
487                    refreshed_credentials = true;
488                    continue;
489                } else if let Some(duration) = response.retry_delay {
490                    tokio::time::sleep(duration).await;
491                    continue;
492                }
493
494                return Err(Error::ResponseError(response));
495            }
496            Err(Error::Reqwest(error)) => {
497                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
498                    tokio::time::sleep(duration).await;
499                    continue;
500                }
501
502                return Err(Error::Reqwest(error));
503            }
504            Err(Error::Io(error)) => {
505                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
506                    tokio::time::sleep(duration).await;
507                    continue;
508                }
509
510                return Err(Error::Io(error));
511            }
512            Err(error) => return Err(error),
513        }
514    }
515}
516async fn get_default_endpoint_inner(
517    configuration: &configuration::Configuration,
518    backoff: &mut ExponentialBackoff,
519    quantum_processor_id: &str,
520) -> Result<crate::models::Endpoint, Error<GetDefaultEndpointError>> {
521    let local_var_configuration = configuration;
522
523    let local_var_client = &local_var_configuration.client;
524
525    let local_var_uri_str = format!(
526        "{}/v1/quantumProcessors/{quantumProcessorId}/endpoints:getDefault",
527        local_var_configuration.qcs_config.api_url(),
528        quantumProcessorId = crate::apis::urlencode(quantum_processor_id)
529    );
530    let mut local_var_req_builder =
531        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
532
533    #[cfg(feature = "tracing")]
534    {
535        // Ignore parsing errors if the URL is invalid for some reason.
536        // If it is invalid, it will turn up as an error later when actually making the request.
537        let local_var_do_tracing = local_var_uri_str
538            .parse::<::url::Url>()
539            .ok()
540            .is_none_or(|url| {
541                configuration
542                    .qcs_config
543                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
544            });
545
546        if local_var_do_tracing {
547            ::tracing::debug!(
548                url=%local_var_uri_str,
549                method="GET",
550                "making get_default_endpoint request",
551            );
552        }
553    }
554
555    // Use the QCS Bearer token if a client OAuthSession is present,
556    // but do not require one when the security schema says it is optional.
557    {
558        use qcs_api_client_common::configuration::TokenError;
559
560        #[allow(
561            clippy::nonminimal_bool,
562            clippy::eq_op,
563            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
564        )]
565        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
566
567        let token = local_var_configuration
568            .qcs_config
569            .get_bearer_access_token()
570            .await;
571
572        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
573            // the client is configured without any OAuthSession, but this call does not require one.
574            #[cfg(feature = "tracing")]
575            tracing::debug!(
576                "No client credentials found, but this call does not require authentication."
577            );
578        } else {
579            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
580        }
581    }
582
583    let local_var_req = local_var_req_builder.build()?;
584    let local_var_resp = local_var_client.execute(local_var_req).await?;
585
586    let local_var_status = local_var_resp.status();
587
588    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
589        let local_var_content = local_var_resp.text().await?;
590        serde_json::from_str(&local_var_content).map_err(Error::from)
591    } else {
592        let local_var_retry_delay =
593            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
594        let local_var_content = local_var_resp.text().await?;
595        let local_var_entity: Option<GetDefaultEndpointError> =
596            serde_json::from_str(&local_var_content).ok();
597        let local_var_error = ResponseContent {
598            status: local_var_status,
599            content: local_var_content,
600            entity: local_var_entity,
601            retry_delay: local_var_retry_delay,
602        };
603        Err(Error::ResponseError(local_var_error))
604    }
605}
606
607/// Retrieve the endpoint set as \"default\" for the given Quantum Processor.  If no endpoint is set as the default, return \"not found.\"
608pub async fn get_default_endpoint(
609    configuration: &configuration::Configuration,
610    quantum_processor_id: &str,
611) -> Result<crate::models::Endpoint, Error<GetDefaultEndpointError>> {
612    let mut backoff = configuration.backoff.clone();
613    let mut refreshed_credentials = false;
614    let method = reqwest::Method::GET;
615    loop {
616        let result =
617            get_default_endpoint_inner(configuration, &mut backoff, quantum_processor_id.clone())
618                .await;
619
620        match result {
621            Ok(result) => return Ok(result),
622            Err(Error::ResponseError(response)) => {
623                if !refreshed_credentials
624                    && matches!(
625                        response.status,
626                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
627                    )
628                {
629                    configuration.qcs_config.refresh().await?;
630                    refreshed_credentials = true;
631                    continue;
632                } else if let Some(duration) = response.retry_delay {
633                    tokio::time::sleep(duration).await;
634                    continue;
635                }
636
637                return Err(Error::ResponseError(response));
638            }
639            Err(Error::Reqwest(error)) => {
640                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
641                    tokio::time::sleep(duration).await;
642                    continue;
643                }
644
645                return Err(Error::Reqwest(error));
646            }
647            Err(Error::Io(error)) => {
648                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
649                    tokio::time::sleep(duration).await;
650                    continue;
651                }
652
653                return Err(Error::Io(error));
654            }
655            Err(error) => return Err(error),
656        }
657    }
658}
659async fn get_endpoint_inner(
660    configuration: &configuration::Configuration,
661    backoff: &mut ExponentialBackoff,
662    endpoint_id: &str,
663) -> Result<crate::models::Endpoint, Error<GetEndpointError>> {
664    let local_var_configuration = configuration;
665
666    let local_var_client = &local_var_configuration.client;
667
668    let local_var_uri_str = format!(
669        "{}/v1/endpoints/{endpointId}",
670        local_var_configuration.qcs_config.api_url(),
671        endpointId = crate::apis::urlencode(endpoint_id)
672    );
673    let mut local_var_req_builder =
674        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
675
676    #[cfg(feature = "tracing")]
677    {
678        // Ignore parsing errors if the URL is invalid for some reason.
679        // If it is invalid, it will turn up as an error later when actually making the request.
680        let local_var_do_tracing = local_var_uri_str
681            .parse::<::url::Url>()
682            .ok()
683            .is_none_or(|url| {
684                configuration
685                    .qcs_config
686                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
687            });
688
689        if local_var_do_tracing {
690            ::tracing::debug!(
691                url=%local_var_uri_str,
692                method="GET",
693                "making get_endpoint request",
694            );
695        }
696    }
697
698    // Use the QCS Bearer token if a client OAuthSession is present,
699    // but do not require one when the security schema says it is optional.
700    {
701        use qcs_api_client_common::configuration::TokenError;
702
703        #[allow(
704            clippy::nonminimal_bool,
705            clippy::eq_op,
706            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
707        )]
708        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
709
710        let token = local_var_configuration
711            .qcs_config
712            .get_bearer_access_token()
713            .await;
714
715        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
716            // the client is configured without any OAuthSession, but this call does not require one.
717            #[cfg(feature = "tracing")]
718            tracing::debug!(
719                "No client credentials found, but this call does not require authentication."
720            );
721        } else {
722            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
723        }
724    }
725
726    let local_var_req = local_var_req_builder.build()?;
727    let local_var_resp = local_var_client.execute(local_var_req).await?;
728
729    let local_var_status = local_var_resp.status();
730
731    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
732        let local_var_content = local_var_resp.text().await?;
733        serde_json::from_str(&local_var_content).map_err(Error::from)
734    } else {
735        let local_var_retry_delay =
736            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
737        let local_var_content = local_var_resp.text().await?;
738        let local_var_entity: Option<GetEndpointError> =
739            serde_json::from_str(&local_var_content).ok();
740        let local_var_error = ResponseContent {
741            status: local_var_status,
742            content: local_var_content,
743            entity: local_var_entity,
744            retry_delay: local_var_retry_delay,
745        };
746        Err(Error::ResponseError(local_var_error))
747    }
748}
749
750/// Retrieve a specific endpoint by its ID.
751pub async fn get_endpoint(
752    configuration: &configuration::Configuration,
753    endpoint_id: &str,
754) -> Result<crate::models::Endpoint, Error<GetEndpointError>> {
755    let mut backoff = configuration.backoff.clone();
756    let mut refreshed_credentials = false;
757    let method = reqwest::Method::GET;
758    loop {
759        let result = get_endpoint_inner(configuration, &mut backoff, endpoint_id.clone()).await;
760
761        match result {
762            Ok(result) => return Ok(result),
763            Err(Error::ResponseError(response)) => {
764                if !refreshed_credentials
765                    && matches!(
766                        response.status,
767                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
768                    )
769                {
770                    configuration.qcs_config.refresh().await?;
771                    refreshed_credentials = true;
772                    continue;
773                } else if let Some(duration) = response.retry_delay {
774                    tokio::time::sleep(duration).await;
775                    continue;
776                }
777
778                return Err(Error::ResponseError(response));
779            }
780            Err(Error::Reqwest(error)) => {
781                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
782                    tokio::time::sleep(duration).await;
783                    continue;
784                }
785
786                return Err(Error::Reqwest(error));
787            }
788            Err(Error::Io(error)) => {
789                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
790                    tokio::time::sleep(duration).await;
791                    continue;
792                }
793
794                return Err(Error::Io(error));
795            }
796            Err(error) => return Err(error),
797        }
798    }
799}
800async fn list_endpoints_inner(
801    configuration: &configuration::Configuration,
802    backoff: &mut ExponentialBackoff,
803    filter: Option<&str>,
804    page_size: Option<i64>,
805    page_token: Option<&str>,
806) -> Result<crate::models::ListEndpointsResponse, Error<ListEndpointsError>> {
807    let local_var_configuration = configuration;
808
809    let local_var_client = &local_var_configuration.client;
810
811    let local_var_uri_str = format!(
812        "{}/v1/endpoints",
813        local_var_configuration.qcs_config.api_url()
814    );
815    let mut local_var_req_builder =
816        local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
817
818    #[cfg(feature = "tracing")]
819    {
820        // Ignore parsing errors if the URL is invalid for some reason.
821        // If it is invalid, it will turn up as an error later when actually making the request.
822        let local_var_do_tracing = local_var_uri_str
823            .parse::<::url::Url>()
824            .ok()
825            .is_none_or(|url| {
826                configuration
827                    .qcs_config
828                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
829            });
830
831        if local_var_do_tracing {
832            ::tracing::debug!(
833                url=%local_var_uri_str,
834                method="GET",
835                "making list_endpoints request",
836            );
837        }
838    }
839
840    if let Some(ref local_var_str) = filter {
841        local_var_req_builder =
842            local_var_req_builder.query(&[("filter", &local_var_str.to_string())]);
843    }
844    if let Some(ref local_var_str) = page_size {
845        local_var_req_builder =
846            local_var_req_builder.query(&[("pageSize", &local_var_str.to_string())]);
847    }
848    if let Some(ref local_var_str) = page_token {
849        local_var_req_builder =
850            local_var_req_builder.query(&[("pageToken", &local_var_str.to_string())]);
851    }
852
853    // Use the QCS Bearer token if a client OAuthSession is present,
854    // but do not require one when the security schema says it is optional.
855    {
856        use qcs_api_client_common::configuration::TokenError;
857
858        #[allow(
859            clippy::nonminimal_bool,
860            clippy::eq_op,
861            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
862        )]
863        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
864
865        let token = local_var_configuration
866            .qcs_config
867            .get_bearer_access_token()
868            .await;
869
870        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
871            // the client is configured without any OAuthSession, but this call does not require one.
872            #[cfg(feature = "tracing")]
873            tracing::debug!(
874                "No client credentials found, but this call does not require authentication."
875            );
876        } else {
877            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
878        }
879    }
880
881    let local_var_req = local_var_req_builder.build()?;
882    let local_var_resp = local_var_client.execute(local_var_req).await?;
883
884    let local_var_status = local_var_resp.status();
885
886    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
887        let local_var_content = local_var_resp.text().await?;
888        serde_json::from_str(&local_var_content).map_err(Error::from)
889    } else {
890        let local_var_retry_delay =
891            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
892        let local_var_content = local_var_resp.text().await?;
893        let local_var_entity: Option<ListEndpointsError> =
894            serde_json::from_str(&local_var_content).ok();
895        let local_var_error = ResponseContent {
896            status: local_var_status,
897            content: local_var_content,
898            entity: local_var_entity,
899            retry_delay: local_var_retry_delay,
900        };
901        Err(Error::ResponseError(local_var_error))
902    }
903}
904
905/// List all endpoints, optionally filtering by attribute.
906pub async fn list_endpoints(
907    configuration: &configuration::Configuration,
908    filter: Option<&str>,
909    page_size: Option<i64>,
910    page_token: Option<&str>,
911) -> Result<crate::models::ListEndpointsResponse, Error<ListEndpointsError>> {
912    let mut backoff = configuration.backoff.clone();
913    let mut refreshed_credentials = false;
914    let method = reqwest::Method::GET;
915    loop {
916        let result = list_endpoints_inner(
917            configuration,
918            &mut backoff,
919            filter.clone(),
920            page_size.clone(),
921            page_token.clone(),
922        )
923        .await;
924
925        match result {
926            Ok(result) => return Ok(result),
927            Err(Error::ResponseError(response)) => {
928                if !refreshed_credentials
929                    && matches!(
930                        response.status,
931                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
932                    )
933                {
934                    configuration.qcs_config.refresh().await?;
935                    refreshed_credentials = true;
936                    continue;
937                } else if let Some(duration) = response.retry_delay {
938                    tokio::time::sleep(duration).await;
939                    continue;
940                }
941
942                return Err(Error::ResponseError(response));
943            }
944            Err(Error::Reqwest(error)) => {
945                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
946                    tokio::time::sleep(duration).await;
947                    continue;
948                }
949
950                return Err(Error::Reqwest(error));
951            }
952            Err(Error::Io(error)) => {
953                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
954                    tokio::time::sleep(duration).await;
955                    continue;
956                }
957
958                return Err(Error::Io(error));
959            }
960            Err(error) => return Err(error),
961        }
962    }
963}
964async fn restart_endpoint_inner(
965    configuration: &configuration::Configuration,
966    backoff: &mut ExponentialBackoff,
967    endpoint_id: &str,
968    restart_endpoint_request: Option<crate::models::RestartEndpointRequest>,
969) -> Result<(), Error<RestartEndpointError>> {
970    let local_var_configuration = configuration;
971
972    let local_var_client = &local_var_configuration.client;
973
974    let local_var_uri_str = format!(
975        "{}/v1/endpoints/{endpointId}:restart",
976        local_var_configuration.qcs_config.api_url(),
977        endpointId = crate::apis::urlencode(endpoint_id)
978    );
979    let mut local_var_req_builder =
980        local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str());
981
982    #[cfg(feature = "tracing")]
983    {
984        // Ignore parsing errors if the URL is invalid for some reason.
985        // If it is invalid, it will turn up as an error later when actually making the request.
986        let local_var_do_tracing = local_var_uri_str
987            .parse::<::url::Url>()
988            .ok()
989            .is_none_or(|url| {
990                configuration
991                    .qcs_config
992                    .should_trace(&::urlpattern::UrlPatternMatchInput::Url(url))
993            });
994
995        if local_var_do_tracing {
996            ::tracing::debug!(
997                url=%local_var_uri_str,
998                method="POST",
999                "making restart_endpoint request",
1000            );
1001        }
1002    }
1003
1004    // Use the QCS Bearer token if a client OAuthSession is present,
1005    // but do not require one when the security schema says it is optional.
1006    {
1007        use qcs_api_client_common::configuration::TokenError;
1008
1009        #[allow(
1010            clippy::nonminimal_bool,
1011            clippy::eq_op,
1012            reason = "Logic must be done at runtime since it cannot be handled by the mustache template engine."
1013        )]
1014        let is_jwt_bearer_optional: bool = false || "JWTBearer" == "JWTBearerOptional";
1015
1016        let token = local_var_configuration
1017            .qcs_config
1018            .get_bearer_access_token()
1019            .await;
1020
1021        if is_jwt_bearer_optional && matches!(token, Err(TokenError::NoCredentials)) {
1022            // the client is configured without any OAuthSession, but this call does not require one.
1023            #[cfg(feature = "tracing")]
1024            tracing::debug!(
1025                "No client credentials found, but this call does not require authentication."
1026            );
1027        } else {
1028            local_var_req_builder = local_var_req_builder.bearer_auth(token?.secret());
1029        }
1030    }
1031
1032    local_var_req_builder = local_var_req_builder.json(&restart_endpoint_request);
1033
1034    let local_var_req = local_var_req_builder.build()?;
1035    let local_var_resp = local_var_client.execute(local_var_req).await?;
1036
1037    let local_var_status = local_var_resp.status();
1038
1039    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
1040        Ok(())
1041    } else {
1042        let local_var_retry_delay =
1043            duration_from_response(local_var_resp.status(), local_var_resp.headers(), backoff);
1044        let local_var_content = local_var_resp.text().await?;
1045        let local_var_entity: Option<RestartEndpointError> =
1046            serde_json::from_str(&local_var_content).ok();
1047        let local_var_error = ResponseContent {
1048            status: local_var_status,
1049            content: local_var_content,
1050            entity: local_var_entity,
1051            retry_delay: local_var_retry_delay,
1052        };
1053        Err(Error::ResponseError(local_var_error))
1054    }
1055}
1056
1057/// Restart an entire endpoint or a single component within an endpoint.
1058pub async fn restart_endpoint(
1059    configuration: &configuration::Configuration,
1060    endpoint_id: &str,
1061    restart_endpoint_request: Option<crate::models::RestartEndpointRequest>,
1062) -> Result<(), Error<RestartEndpointError>> {
1063    let mut backoff = configuration.backoff.clone();
1064    let mut refreshed_credentials = false;
1065    let method = reqwest::Method::POST;
1066    loop {
1067        let result = restart_endpoint_inner(
1068            configuration,
1069            &mut backoff,
1070            endpoint_id.clone(),
1071            restart_endpoint_request.clone(),
1072        )
1073        .await;
1074
1075        match result {
1076            Ok(result) => return Ok(result),
1077            Err(Error::ResponseError(response)) => {
1078                if !refreshed_credentials
1079                    && matches!(
1080                        response.status,
1081                        StatusCode::FORBIDDEN | StatusCode::UNAUTHORIZED
1082                    )
1083                {
1084                    configuration.qcs_config.refresh().await?;
1085                    refreshed_credentials = true;
1086                    continue;
1087                } else if let Some(duration) = response.retry_delay {
1088                    tokio::time::sleep(duration).await;
1089                    continue;
1090                }
1091
1092                return Err(Error::ResponseError(response));
1093            }
1094            Err(Error::Reqwest(error)) => {
1095                if let Some(duration) = duration_from_reqwest_error(&method, &error, &mut backoff) {
1096                    tokio::time::sleep(duration).await;
1097                    continue;
1098                }
1099
1100                return Err(Error::Reqwest(error));
1101            }
1102            Err(Error::Io(error)) => {
1103                if let Some(duration) = duration_from_io_error(&method, &error, &mut backoff) {
1104                    tokio::time::sleep(duration).await;
1105                    continue;
1106                }
1107
1108                return Err(Error::Io(error));
1109            }
1110            Err(error) => return Err(error),
1111        }
1112    }
1113}