Skip to main content

timeweb_rs/apis/
images_api.rs

1/*
2 * Документация публичного API
3 *
4 * # Введение API Timeweb Cloud позволяет вам управлять ресурсами в облаке программным способом с использованием обычных HTTP-запросов.  Множество функций, которые доступны в панели управления Timeweb Cloud, также доступны через API, что позволяет вам автоматизировать ваши собственные сценарии.  В этой документации сперва будет описан общий дизайн и принципы работы API, а после этого конкретные конечные точки. Также будут приведены примеры запросов к ним.   ## Запросы Запросы должны выполняться по протоколу `HTTPS`, чтобы гарантировать шифрование транзакций. Поддерживаются следующие методы запроса: |Метод|Применение| |--- |--- | |GET|Извлекает данные о коллекциях и отдельных ресурсах.| |POST|Для коллекций создает новый ресурс этого типа. Также используется для выполнения действий с конкретным ресурсом.| |PUT|Обновляет существующий ресурс.| |PATCH|Некоторые ресурсы поддерживают частичное обновление, то есть обновление только части атрибутов ресурса, в этом случае вместо метода PUT будет использован PATCH.| |DELETE|Удаляет ресурс.|  Методы `POST`, `PUT` и `PATCH` могут включать объект в тело запроса с типом содержимого `application/json`.  ### Параметры в запросах Некоторые коллекции поддерживают пагинацию, поиск или сортировку в запросах. В параметрах запроса требуется передать: - `limit` — обозначает количество записей, которое необходимо вернуть  - `offset` — указывает на смещение, относительно начала списка  - `search` — позволяет указать набор символов для поиска  - `sort` — можно задать правило сортировки коллекции  ## Ответы Запросы вернут один из следующих кодов состояния ответа HTTP:  |Статус|Описание| |--- |--- | |200 OK|Действие с ресурсом было выполнено успешно.| |201 Created|Ресурс был успешно создан. При этом ресурс может быть как уже готовым к использованию, так и находиться в процессе запуска.| |204 No Content|Действие с ресурсом было выполнено успешно, и ответ не содержит дополнительной информации в теле.| |400 Bad Request|Был отправлен неверный запрос, например, в нем отсутствуют обязательные параметры и т. д. Тело ответа будет содержать дополнительную информацию об ошибке.| |401 Unauthorized|Ошибка аутентификации.| |403 Forbidden|Аутентификация прошла успешно, но недостаточно прав для выполнения действия.| |404 Not Found|Запрашиваемый ресурс не найден.| |409 Conflict|Запрос конфликтует с текущим состоянием.| |423 Locked|Ресурс из запроса заблокирован от применения к нему указанного метода.| |429 Too Many Requests|Был достигнут лимит по количеству запросов в единицу времени.| |500 Internal Server Error|При выполнении запроса произошла какая-то внутренняя ошибка. Чтобы решить эту проблему, лучше всего создать тикет в панели управления.|  ### Структура успешного ответа Все конечные точки будут возвращать данные в формате `JSON`. Ответы на `GET`-запросы будут иметь на верхнем уровне следующую структуру атрибутов:  |Название поля|Тип|Описание| |--- |--- |--- | |[entity_name]|object, object[], string[], number[], boolean|Динамическое поле, которое будет меняться в зависимости от запрашиваемого ресурса и будет содержать все атрибуты, необходимые для описания этого ресурса. Например, при запросе списка баз данных будет возвращаться поле `dbs`, а при запросе конкретного облачного сервера `server`. Для некоторых конечных точек в ответе может возвращаться сразу несколько ресурсов.| |meta|object|Опционально. Объект, который содержит вспомогательную информацию о ресурсе. Чаще всего будет встречаться при запросе коллекций и содержать поле `total`, которое будет указывать на количество элементов в коллекции.| |response_id|string|Опционально. В большинстве случаев в ответе будет содержаться ID ответа в формате UUIDv4, который однозначно указывает на ваш запрос внутри нашей системы. Если вам потребуется задать вопрос нашей поддержке, приложите к вопросу этот ID— так мы сможем найти ответ на него намного быстрее. Также вы можете использовать этот ID, чтобы убедиться, что это новый ответ на запрос и результат не был получен из кэша.|  Пример запроса на получение списка SSH-ключей: ```     HTTP/2.0 200 OK     {       \"ssh_keys\":[           {             \"body\":\"ssh-rsa AAAAB3NzaC1sdfghjkOAsBwWhs= example@device.local\",             \"created_at\":\"2021-09-15T19:52:27Z\",             \"expired_at\":null,             \"id\":5297,             \"is_default\":false,             \"name\":\"example@device.local\",             \"used_at\":null,             \"used_by\":[]           }       ],       \"meta\":{           \"total\":1       },       \"response_id\":\"94608d15-8672-4eed-8ab6-28bd6fa3cdf7\"     } ```  ### Структура ответа с ошибкой |Название поля|Тип|Описание| |--- |--- |--- | |status_code|number|Короткий числовой идентификатор ошибки.| |error_code|string|Короткий текстовый идентификатор ошибки, который уточняет числовой идентификатор и удобен для программной обработки. Самый простой пример — это код `not_found` для ошибки 404.| |message|string, string[]|Опционально. В большинстве случаев в ответе будет содержаться человекочитаемое подробное описание ошибки или ошибок, которые помогут понять, что нужно исправить.| |response_id|string|Опционально. В большинстве случае в ответе будет содержаться ID ответа в формате UUIDv4, который однозначно указывает на ваш запрос внутри нашей системы. Если вам потребуется задать вопрос нашей поддержке, приложите к вопросу этот ID — так мы сможем найти ответ на него намного быстрее.|  Пример: ```     HTTP/2.0 403 Forbidden     {       \"status_code\": 403,       \"error_code\":  \"forbidden\",       \"message\":     \"You do not have access for the attempted action\",       \"response_id\": \"94608d15-8672-4eed-8ab6-28bd6fa3cdf7\"     } ```  ## Статусы ресурсов Важно учесть, что при создании большинства ресурсов внутри платформы вам будет сразу возвращен ответ от сервера со статусом `200 OK` или `201 Created` и ID созданного ресурса в теле ответа, но при этом этот ресурс может быть ещё в *состоянии запуска*.  Для того чтобы понять, в каком состоянии сейчас находится ваш ресурс, мы добавили поле `status` в ответ на получение информации о ресурсе.  Список статусов будет отличаться в зависимости от типа ресурса. Увидеть поддерживаемый список статусов вы сможете в описании каждого конкретного ресурса.     ## Ограничение скорости запросов (Rate Limiting) Чтобы обеспечить стабильность для всех пользователей, Timeweb Cloud защищает API от всплесков входящего трафика, анализируя количество запросов c каждого аккаунта к каждой конечной точке.  Если ваше приложение отправляет более 20 запросов в секунду на одну конечную точку, то для этого запроса API может вернуть код состояния HTTP `429 Too Many Requests`.   ## Аутентификация Доступ к API осуществляется с помощью JWT-токена. Токенами можно управлять внутри панели управления Timeweb Cloud в разделе *API и Terraform*.  Токен необходимо передавать в заголовке каждого запроса в формате: ```   Authorization: Bearer $TIMEWEB_CLOUD_TOKEN ```  ## Формат примеров API Примеры в этой документации описаны с помощью `curl`, HTTP-клиента командной строки. На компьютерах `Linux` и `macOS` обычно по умолчанию установлен `curl`, и он доступен для загрузки на всех популярных платформах, включая `Windows`.  Каждый пример разделен на несколько строк символом `\\`, который совместим с `bash`. Типичный пример выглядит так: ```   curl -X PATCH      -H \"Content-Type: application/json\"      -H \"Authorization: Bearer $TIMEWEB_CLOUD_TOKEN\"      -d '{\"name\":\"Cute Corvus\",\"comment\":\"Development Server\"}'      \"https://api.timeweb.cloud/api/v1/dedicated/1051\" ``` - Параметр `-X` задает метод запроса. Для согласованности метод будет указан во всех примерах, даже если он явно не требуется для методов `GET`. - Строки `-H` задают требуемые HTTP-заголовки. - Примеры, для которых требуется объект JSON в теле запроса, передают требуемые данные через параметр `-d`.  Чтобы использовать приведенные примеры, не подставляя каждый раз в них свой токен, вы можете добавить токен один раз в переменные окружения в вашей консоли. Например, на `Linux` это можно сделать с помощью команды:  ``` TIMEWEB_CLOUD_TOKEN=\"token\" ```  После этого токен будет автоматически подставляться в ваши запросы.  Обратите внимание, что все значения в этой документации являются примерами. Не полагайтесь на IDы операционных систем, тарифов и т.д., используемые в примерах. Используйте соответствующую конечную точку для получения значений перед созданием ресурсов.   ## Версионирование API построено согласно принципам [семантического версионирования](https://semver.org/lang/ru). Это значит, что мы гарантируем обратную совместимость всех изменений в пределах одной мажорной версии.  Мажорная версия каждой конечной точки обозначается в пути запроса, например, запрос `/api/v1/servers` указывает, что этот метод имеет версию 1.
5 *
6 * The version of the OpenAPI document: 1.0.0
7 * Contact: info@timeweb.cloud
8 * Generated by: https://openapi-generator.tech
9 */
10
11use reqwest;
12use serde::{Deserialize, Serialize, de::Error as _};
13
14use super::{ContentType, Error, configuration};
15use crate::{apis::ResponseContent, models};
16
17/// struct for typed errors of method [`create_image`]
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(untagged)]
20pub enum CreateImageError {
21    Status400(models::GetFinances400Response),
22    Status401(models::GetFinances401Response),
23    Status429(models::GetFinances429Response),
24    Status500(models::GetFinances500Response),
25    UnknownValue(serde_json::Value)
26}
27
28/// struct for typed errors of method [`create_image_download_url`]
29#[derive(Debug, Clone, Serialize, Deserialize)]
30#[serde(untagged)]
31pub enum CreateImageDownloadUrlError {
32    Status400(models::GetFinances400Response),
33    Status401(models::GetFinances401Response),
34    Status404(models::GetImage404Response),
35    Status409(models::BaseError),
36    Status429(models::GetFinances429Response),
37    Status500(models::GetFinances500Response),
38    UnknownValue(serde_json::Value)
39}
40
41/// struct for typed errors of method [`delete_image`]
42#[derive(Debug, Clone, Serialize, Deserialize)]
43#[serde(untagged)]
44pub enum DeleteImageError {
45    Status400(models::GetFinances400Response),
46    Status401(models::GetFinances401Response),
47    Status429(models::GetFinances429Response),
48    Status500(models::GetFinances500Response),
49    UnknownValue(serde_json::Value)
50}
51
52/// struct for typed errors of method [`delete_image_download_url`]
53#[derive(Debug, Clone, Serialize, Deserialize)]
54#[serde(untagged)]
55pub enum DeleteImageDownloadUrlError {
56    Status400(models::GetFinances400Response),
57    Status401(models::GetFinances401Response),
58    Status429(models::GetFinances429Response),
59    Status500(models::GetFinances500Response),
60    UnknownValue(serde_json::Value)
61}
62
63/// struct for typed errors of method [`get_image`]
64#[derive(Debug, Clone, Serialize, Deserialize)]
65#[serde(untagged)]
66pub enum GetImageError {
67    Status400(models::GetFinances400Response),
68    Status401(models::GetFinances401Response),
69    Status404(models::GetImage404Response),
70    Status429(models::GetFinances429Response),
71    Status500(models::GetFinances500Response),
72    UnknownValue(serde_json::Value)
73}
74
75/// struct for typed errors of method [`get_image_download_url`]
76#[derive(Debug, Clone, Serialize, Deserialize)]
77#[serde(untagged)]
78pub enum GetImageDownloadUrlError {
79    Status400(models::GetFinances400Response),
80    Status401(models::GetFinances401Response),
81    Status404(models::GetImage404Response),
82    Status429(models::GetFinances429Response),
83    Status500(models::GetFinances500Response),
84    UnknownValue(serde_json::Value)
85}
86
87/// struct for typed errors of method [`get_image_download_urls`]
88#[derive(Debug, Clone, Serialize, Deserialize)]
89#[serde(untagged)]
90pub enum GetImageDownloadUrlsError {
91    Status400(models::GetFinances400Response),
92    Status401(models::GetFinances401Response),
93    Status404(models::GetImage404Response),
94    Status429(models::GetFinances429Response),
95    Status500(models::GetFinances500Response),
96    UnknownValue(serde_json::Value)
97}
98
99/// struct for typed errors of method [`get_images`]
100#[derive(Debug, Clone, Serialize, Deserialize)]
101#[serde(untagged)]
102pub enum GetImagesError {
103    Status400(models::GetFinances400Response),
104    Status401(models::GetFinances401Response),
105    Status429(models::GetFinances429Response),
106    Status500(models::GetFinances500Response),
107    UnknownValue(serde_json::Value)
108}
109
110/// struct for typed errors of method [`update_image`]
111#[derive(Debug, Clone, Serialize, Deserialize)]
112#[serde(untagged)]
113pub enum UpdateImageError {
114    Status400(models::GetFinances400Response),
115    Status401(models::GetFinances401Response),
116    Status404(models::GetImage404Response),
117    Status429(models::GetFinances429Response),
118    Status500(models::GetFinances500Response),
119    UnknownValue(serde_json::Value)
120}
121
122/// struct for typed errors of method [`upload_image`]
123#[derive(Debug, Clone, Serialize, Deserialize)]
124#[serde(untagged)]
125pub enum UploadImageError {
126    Status400(models::GetFinances400Response),
127    Status401(models::GetFinances401Response),
128    Status429(models::GetFinances429Response),
129    Status500(models::GetFinances500Response),
130    UnknownValue(serde_json::Value)
131}
132
133/// Чтобы создать образ, отправьте POST запрос в `/api/v1/images`, задав
134/// необходимые атрибуты.   Для загрузки собственного образа вам нужно отправить
135/// параметры `location`, `os` и не указывать `disk_id`. Поддерживается два
136/// способа загрузки:  1. По ссылке. Для этого укажите `upload_url` с ссылкой на
137/// загрузку образа 2. Из файла. Для этого воспользуйтесь методом POST
138/// `/api/v1/images/{image_id}` Образ будет создан с использованием
139/// предоставленной информации.    Тело ответа будет содержать объект JSON с
140/// информацией о созданном образе.
141pub async fn create_image(
142    configuration: &configuration::Configuration,
143    image_in_api: models::ImageInApi
144) -> Result<models::CreateImage201Response, Error<CreateImageError>> {
145    // add a prefix to parameters to efficiently prevent name collisions
146    let p_body_image_in_api = image_in_api;
147
148    let uri_str = format!("{}/api/v1/images", configuration.base_path);
149    let mut req_builder = configuration
150        .client
151        .request(reqwest::Method::POST, &uri_str);
152
153    if let Some(ref user_agent) = configuration.user_agent {
154        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
155    }
156    if let Some(ref token) = configuration.bearer_access_token {
157        req_builder = req_builder.bearer_auth(token.to_owned());
158    };
159    req_builder = req_builder.json(&p_body_image_in_api);
160
161    let req = req_builder.build()?;
162    let resp = configuration.client.execute(req).await?;
163
164    let status = resp.status();
165    let content_type = resp
166        .headers()
167        .get("content-type")
168        .and_then(|v| v.to_str().ok())
169        .unwrap_or("application/octet-stream");
170    let content_type = super::ContentType::from(content_type);
171
172    if !status.is_client_error() && !status.is_server_error() {
173        let content = resp.text().await?;
174        match content_type {
175            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
176            ContentType::Text => {
177                return Err(Error::from(serde_json::Error::custom(
178                    "Received `text/plain` content type response that cannot be converted to `models::CreateImage201Response`"
179                )));
180            }
181            ContentType::Unsupported(unknown_type) => {
182                return Err(Error::from(serde_json::Error::custom(format!(
183                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateImage201Response`"
184                ))));
185            }
186        }
187    } else {
188        let content = resp.text().await?;
189        let entity: Option<CreateImageError> = serde_json::from_str(&content).ok();
190        Err(Error::ResponseError(ResponseContent {
191            status,
192            content,
193            entity
194        }))
195    }
196}
197
198/// Чтобы создать ссылку на скачивание образа, отправьте запрос POST в
199/// `/api/v1/images/{image_id}/download-url`.
200pub async fn create_image_download_url(
201    configuration: &configuration::Configuration,
202    image_id: &str,
203    image_url_in: models::ImageUrlIn
204) -> Result<models::CreateImageDownloadUrl201Response, Error<CreateImageDownloadUrlError>> {
205    // add a prefix to parameters to efficiently prevent name collisions
206    let p_path_image_id = image_id;
207    let p_body_image_url_in = image_url_in;
208
209    let uri_str = format!(
210        "{}/api/v1/images/{image_id}/download-url",
211        configuration.base_path,
212        image_id = crate::apis::urlencode(p_path_image_id)
213    );
214    let mut req_builder = configuration
215        .client
216        .request(reqwest::Method::POST, &uri_str);
217
218    if let Some(ref user_agent) = configuration.user_agent {
219        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
220    }
221    if let Some(ref token) = configuration.bearer_access_token {
222        req_builder = req_builder.bearer_auth(token.to_owned());
223    };
224    req_builder = req_builder.json(&p_body_image_url_in);
225
226    let req = req_builder.build()?;
227    let resp = configuration.client.execute(req).await?;
228
229    let status = resp.status();
230    let content_type = resp
231        .headers()
232        .get("content-type")
233        .and_then(|v| v.to_str().ok())
234        .unwrap_or("application/octet-stream");
235    let content_type = super::ContentType::from(content_type);
236
237    if !status.is_client_error() && !status.is_server_error() {
238        let content = resp.text().await?;
239        match content_type {
240            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
241            ContentType::Text => {
242                return Err(Error::from(serde_json::Error::custom(
243                    "Received `text/plain` content type response that cannot be converted to `models::CreateImageDownloadUrl201Response`"
244                )));
245            }
246            ContentType::Unsupported(unknown_type) => {
247                return Err(Error::from(serde_json::Error::custom(format!(
248                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateImageDownloadUrl201Response`"
249                ))));
250            }
251        }
252    } else {
253        let content = resp.text().await?;
254        let entity: Option<CreateImageDownloadUrlError> = serde_json::from_str(&content).ok();
255        Err(Error::ResponseError(ResponseContent {
256            status,
257            content,
258            entity
259        }))
260    }
261}
262
263/// Чтобы удалить образ, отправьте запрос DELETE в `/api/v1/images/{image_id}`.
264pub async fn delete_image(
265    configuration: &configuration::Configuration,
266    image_id: &str
267) -> Result<(), Error<DeleteImageError>> {
268    // add a prefix to parameters to efficiently prevent name collisions
269    let p_path_image_id = image_id;
270
271    let uri_str = format!(
272        "{}/api/v1/images/{image_id}",
273        configuration.base_path,
274        image_id = crate::apis::urlencode(p_path_image_id)
275    );
276    let mut req_builder = configuration
277        .client
278        .request(reqwest::Method::DELETE, &uri_str);
279
280    if let Some(ref user_agent) = configuration.user_agent {
281        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
282    }
283    if let Some(ref token) = configuration.bearer_access_token {
284        req_builder = req_builder.bearer_auth(token.to_owned());
285    };
286
287    let req = req_builder.build()?;
288    let resp = configuration.client.execute(req).await?;
289
290    let status = resp.status();
291
292    if !status.is_client_error() && !status.is_server_error() {
293        Ok(())
294    } else {
295        let content = resp.text().await?;
296        let entity: Option<DeleteImageError> = serde_json::from_str(&content).ok();
297        Err(Error::ResponseError(ResponseContent {
298            status,
299            content,
300            entity
301        }))
302    }
303}
304
305/// Чтобы удалить ссылку на образ, отправьте DELETE запрос в
306/// `/api/v1/images/{image_id}/download-url/{image_url_id}`.
307pub async fn delete_image_download_url(
308    configuration: &configuration::Configuration,
309    image_id: &str,
310    image_url_id: &str
311) -> Result<(), Error<DeleteImageDownloadUrlError>> {
312    // add a prefix to parameters to efficiently prevent name collisions
313    let p_path_image_id = image_id;
314    let p_path_image_url_id = image_url_id;
315
316    let uri_str = format!(
317        "{}/api/v1/images/{image_id}/download-url/{image_url_id}",
318        configuration.base_path,
319        image_id = crate::apis::urlencode(p_path_image_id),
320        image_url_id = crate::apis::urlencode(p_path_image_url_id)
321    );
322    let mut req_builder = configuration
323        .client
324        .request(reqwest::Method::DELETE, &uri_str);
325
326    if let Some(ref user_agent) = configuration.user_agent {
327        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
328    }
329    if let Some(ref token) = configuration.bearer_access_token {
330        req_builder = req_builder.bearer_auth(token.to_owned());
331    };
332
333    let req = req_builder.build()?;
334    let resp = configuration.client.execute(req).await?;
335
336    let status = resp.status();
337
338    if !status.is_client_error() && !status.is_server_error() {
339        Ok(())
340    } else {
341        let content = resp.text().await?;
342        let entity: Option<DeleteImageDownloadUrlError> = serde_json::from_str(&content).ok();
343        Err(Error::ResponseError(ResponseContent {
344            status,
345            content,
346            entity
347        }))
348    }
349}
350
351/// Чтобы получить образ, отправьте запрос GET в `/api/v1/images/{image_id}`.
352pub async fn get_image(
353    configuration: &configuration::Configuration,
354    image_id: &str
355) -> Result<models::CreateImage201Response, Error<GetImageError>> {
356    // add a prefix to parameters to efficiently prevent name collisions
357    let p_path_image_id = image_id;
358
359    let uri_str = format!(
360        "{}/api/v1/images/{image_id}",
361        configuration.base_path,
362        image_id = crate::apis::urlencode(p_path_image_id)
363    );
364    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
365
366    if let Some(ref user_agent) = configuration.user_agent {
367        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
368    }
369    if let Some(ref token) = configuration.bearer_access_token {
370        req_builder = req_builder.bearer_auth(token.to_owned());
371    };
372
373    let req = req_builder.build()?;
374    let resp = configuration.client.execute(req).await?;
375
376    let status = resp.status();
377    let content_type = resp
378        .headers()
379        .get("content-type")
380        .and_then(|v| v.to_str().ok())
381        .unwrap_or("application/octet-stream");
382    let content_type = super::ContentType::from(content_type);
383
384    if !status.is_client_error() && !status.is_server_error() {
385        let content = resp.text().await?;
386        match content_type {
387            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
388            ContentType::Text => {
389                return Err(Error::from(serde_json::Error::custom(
390                    "Received `text/plain` content type response that cannot be converted to `models::CreateImage201Response`"
391                )));
392            }
393            ContentType::Unsupported(unknown_type) => {
394                return Err(Error::from(serde_json::Error::custom(format!(
395                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateImage201Response`"
396                ))));
397            }
398        }
399    } else {
400        let content = resp.text().await?;
401        let entity: Option<GetImageError> = serde_json::from_str(&content).ok();
402        Err(Error::ResponseError(ResponseContent {
403            status,
404            content,
405            entity
406        }))
407    }
408}
409
410/// Чтобы получить информацию о ссылке на скачивание образа, отправьте запрос
411/// GET в `/api/v1/images/{image_id}/download-url/{image_url_id}`.
412pub async fn get_image_download_url(
413    configuration: &configuration::Configuration,
414    image_id: &str,
415    image_url_id: &str
416) -> Result<models::CreateImageDownloadUrl201Response, Error<GetImageDownloadUrlError>> {
417    // add a prefix to parameters to efficiently prevent name collisions
418    let p_path_image_id = image_id;
419    let p_path_image_url_id = image_url_id;
420
421    let uri_str = format!(
422        "{}/api/v1/images/{image_id}/download-url/{image_url_id}",
423        configuration.base_path,
424        image_id = crate::apis::urlencode(p_path_image_id),
425        image_url_id = crate::apis::urlencode(p_path_image_url_id)
426    );
427    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
428
429    if let Some(ref user_agent) = configuration.user_agent {
430        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
431    }
432    if let Some(ref token) = configuration.bearer_access_token {
433        req_builder = req_builder.bearer_auth(token.to_owned());
434    };
435
436    let req = req_builder.build()?;
437    let resp = configuration.client.execute(req).await?;
438
439    let status = resp.status();
440    let content_type = resp
441        .headers()
442        .get("content-type")
443        .and_then(|v| v.to_str().ok())
444        .unwrap_or("application/octet-stream");
445    let content_type = super::ContentType::from(content_type);
446
447    if !status.is_client_error() && !status.is_server_error() {
448        let content = resp.text().await?;
449        match content_type {
450            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
451            ContentType::Text => {
452                return Err(Error::from(serde_json::Error::custom(
453                    "Received `text/plain` content type response that cannot be converted to `models::CreateImageDownloadUrl201Response`"
454                )));
455            }
456            ContentType::Unsupported(unknown_type) => {
457                return Err(Error::from(serde_json::Error::custom(format!(
458                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateImageDownloadUrl201Response`"
459                ))));
460            }
461        }
462    } else {
463        let content = resp.text().await?;
464        let entity: Option<GetImageDownloadUrlError> = serde_json::from_str(&content).ok();
465        Err(Error::ResponseError(ResponseContent {
466            status,
467            content,
468            entity
469        }))
470    }
471}
472
473/// Чтобы получить информацию о ссылках на скачивание образов, отправьте запрос
474/// GET в `/api/v1/images/{image_id}/download-url`.
475pub async fn get_image_download_urls(
476    configuration: &configuration::Configuration,
477    image_id: &str,
478    limit: Option<i32>,
479    offset: Option<i32>
480) -> Result<models::GetImageDownloadUrls200Response, Error<GetImageDownloadUrlsError>> {
481    // add a prefix to parameters to efficiently prevent name collisions
482    let p_path_image_id = image_id;
483    let p_query_limit = limit;
484    let p_query_offset = offset;
485
486    let uri_str = format!(
487        "{}/api/v1/images/{image_id}/download-url",
488        configuration.base_path,
489        image_id = crate::apis::urlencode(p_path_image_id)
490    );
491    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
492
493    if let Some(ref param_value) = p_query_limit {
494        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
495    }
496    if let Some(ref param_value) = p_query_offset {
497        req_builder = req_builder.query(&[("offset", &param_value.to_string())]);
498    }
499    if let Some(ref user_agent) = configuration.user_agent {
500        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
501    }
502    if let Some(ref token) = configuration.bearer_access_token {
503        req_builder = req_builder.bearer_auth(token.to_owned());
504    };
505
506    let req = req_builder.build()?;
507    let resp = configuration.client.execute(req).await?;
508
509    let status = resp.status();
510    let content_type = resp
511        .headers()
512        .get("content-type")
513        .and_then(|v| v.to_str().ok())
514        .unwrap_or("application/octet-stream");
515    let content_type = super::ContentType::from(content_type);
516
517    if !status.is_client_error() && !status.is_server_error() {
518        let content = resp.text().await?;
519        match content_type {
520            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
521            ContentType::Text => {
522                return Err(Error::from(serde_json::Error::custom(
523                    "Received `text/plain` content type response that cannot be converted to `models::GetImageDownloadUrls200Response`"
524                )));
525            }
526            ContentType::Unsupported(unknown_type) => {
527                return Err(Error::from(serde_json::Error::custom(format!(
528                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetImageDownloadUrls200Response`"
529                ))));
530            }
531        }
532    } else {
533        let content = resp.text().await?;
534        let entity: Option<GetImageDownloadUrlsError> = serde_json::from_str(&content).ok();
535        Err(Error::ResponseError(ResponseContent {
536            status,
537            content,
538            entity
539        }))
540    }
541}
542
543/// Чтобы получить список образов, отправьте GET запрос на `/api/v1/images`
544pub async fn get_images(
545    configuration: &configuration::Configuration,
546    limit: Option<i32>,
547    offset: Option<i32>
548) -> Result<models::GetImages200Response, Error<GetImagesError>> {
549    // add a prefix to parameters to efficiently prevent name collisions
550    let p_query_limit = limit;
551    let p_query_offset = offset;
552
553    let uri_str = format!("{}/api/v1/images", configuration.base_path);
554    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
555
556    if let Some(ref param_value) = p_query_limit {
557        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
558    }
559    if let Some(ref param_value) = p_query_offset {
560        req_builder = req_builder.query(&[("offset", &param_value.to_string())]);
561    }
562    if let Some(ref user_agent) = configuration.user_agent {
563        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
564    }
565    if let Some(ref token) = configuration.bearer_access_token {
566        req_builder = req_builder.bearer_auth(token.to_owned());
567    };
568
569    let req = req_builder.build()?;
570    let resp = configuration.client.execute(req).await?;
571
572    let status = resp.status();
573    let content_type = resp
574        .headers()
575        .get("content-type")
576        .and_then(|v| v.to_str().ok())
577        .unwrap_or("application/octet-stream");
578    let content_type = super::ContentType::from(content_type);
579
580    if !status.is_client_error() && !status.is_server_error() {
581        let content = resp.text().await?;
582        match content_type {
583            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
584            ContentType::Text => {
585                return Err(Error::from(serde_json::Error::custom(
586                    "Received `text/plain` content type response that cannot be converted to `models::GetImages200Response`"
587                )));
588            }
589            ContentType::Unsupported(unknown_type) => {
590                return Err(Error::from(serde_json::Error::custom(format!(
591                    "Received `{unknown_type}` content type response that cannot be converted to `models::GetImages200Response`"
592                ))));
593            }
594        }
595    } else {
596        let content = resp.text().await?;
597        let entity: Option<GetImagesError> = serde_json::from_str(&content).ok();
598        Err(Error::ResponseError(ResponseContent {
599            status,
600            content,
601            entity
602        }))
603    }
604}
605
606/// Чтобы обновить только определенные атрибуты образа, отправьте запрос PATCH в
607/// `/api/v1/images/{image_id}`.
608pub async fn update_image(
609    configuration: &configuration::Configuration,
610    image_id: &str,
611    image_update_api: models::ImageUpdateApi
612) -> Result<models::CreateImage201Response, Error<UpdateImageError>> {
613    // add a prefix to parameters to efficiently prevent name collisions
614    let p_path_image_id = image_id;
615    let p_body_image_update_api = image_update_api;
616
617    let uri_str = format!(
618        "{}/api/v1/images/{image_id}",
619        configuration.base_path,
620        image_id = crate::apis::urlencode(p_path_image_id)
621    );
622    let mut req_builder = configuration
623        .client
624        .request(reqwest::Method::PATCH, &uri_str);
625
626    if let Some(ref user_agent) = configuration.user_agent {
627        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
628    }
629    if let Some(ref token) = configuration.bearer_access_token {
630        req_builder = req_builder.bearer_auth(token.to_owned());
631    };
632    req_builder = req_builder.json(&p_body_image_update_api);
633
634    let req = req_builder.build()?;
635    let resp = configuration.client.execute(req).await?;
636
637    let status = resp.status();
638    let content_type = resp
639        .headers()
640        .get("content-type")
641        .and_then(|v| v.to_str().ok())
642        .unwrap_or("application/octet-stream");
643    let content_type = super::ContentType::from(content_type);
644
645    if !status.is_client_error() && !status.is_server_error() {
646        let content = resp.text().await?;
647        match content_type {
648            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
649            ContentType::Text => {
650                return Err(Error::from(serde_json::Error::custom(
651                    "Received `text/plain` content type response that cannot be converted to `models::CreateImage201Response`"
652                )));
653            }
654            ContentType::Unsupported(unknown_type) => {
655                return Err(Error::from(serde_json::Error::custom(format!(
656                    "Received `{unknown_type}` content type response that cannot be converted to `models::CreateImage201Response`"
657                ))));
658            }
659        }
660    } else {
661        let content = resp.text().await?;
662        let entity: Option<UpdateImageError> = serde_json::from_str(&content).ok();
663        Err(Error::ResponseError(ResponseContent {
664            status,
665            content,
666            entity
667        }))
668    }
669}
670
671/// Чтобы загрузить свой образ, отправьте POST запрос в
672/// `/api/v1/images/{image_id}`, отправив файл как `multipart/form-data`, указав
673/// имя файла в заголовке `Content-Disposition`.   Перед загрузкой, нужно
674/// создать образ используя POST `/api/v1/images`, указав параметры `location`,
675/// `os`   Тело ответа будет содержать объект JSON с информацией о загруженном
676/// образе.
677pub async fn upload_image(
678    configuration: &configuration::Configuration,
679    image_id: &str,
680    content_disposition: Option<&str>
681) -> Result<models::UploadImage200Response, Error<UploadImageError>> {
682    // add a prefix to parameters to efficiently prevent name collisions
683    let p_path_image_id = image_id;
684    let p_header_content_disposition = content_disposition;
685
686    let uri_str = format!(
687        "{}/api/v1/images/{image_id}",
688        configuration.base_path,
689        image_id = crate::apis::urlencode(p_path_image_id)
690    );
691    let mut req_builder = configuration
692        .client
693        .request(reqwest::Method::POST, &uri_str);
694
695    if let Some(ref user_agent) = configuration.user_agent {
696        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
697    }
698    if let Some(param_value) = p_header_content_disposition {
699        req_builder = req_builder.header("content-disposition", param_value.to_string());
700    }
701    if let Some(ref token) = configuration.bearer_access_token {
702        req_builder = req_builder.bearer_auth(token.to_owned());
703    };
704
705    let req = req_builder.build()?;
706    let resp = configuration.client.execute(req).await?;
707
708    let status = resp.status();
709    let content_type = resp
710        .headers()
711        .get("content-type")
712        .and_then(|v| v.to_str().ok())
713        .unwrap_or("application/octet-stream");
714    let content_type = super::ContentType::from(content_type);
715
716    if !status.is_client_error() && !status.is_server_error() {
717        let content = resp.text().await?;
718        match content_type {
719            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
720            ContentType::Text => {
721                return Err(Error::from(serde_json::Error::custom(
722                    "Received `text/plain` content type response that cannot be converted to `models::UploadImage200Response`"
723                )));
724            }
725            ContentType::Unsupported(unknown_type) => {
726                return Err(Error::from(serde_json::Error::custom(format!(
727                    "Received `{unknown_type}` content type response that cannot be converted to `models::UploadImage200Response`"
728                ))));
729            }
730        }
731    } else {
732        let content = resp.text().await?;
733        let entity: Option<UploadImageError> = serde_json::from_str(&content).ok();
734        Err(Error::ResponseError(ResponseContent {
735            status,
736            content,
737            entity
738        }))
739    }
740}