You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

537 lines
19 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Dynamix Python SDK
- [Описание](#описание)
- [Системные требования](#системные-требования)
- [Соответствие версий платформы версиям SDK](#соответствие-версий-платформы-версиям-sdk)
- [Зависимости](#зависимости)
- [Установка](#установка)
- [Использование](#использование)
- [Конфигурация](#конфигурация)
- [Функциональный интерфейс](#функциональный-интерфейс)
- [Вызов функции](#вызов-функции)
- [Результат выполнения функции](#результат-выполнения-функции)
- [Соответствие названий](#соответствие-названий)
- [Типы данных SDK](#типы-данных-sdk)
- [Ошибки и исключения (exceptions)](#ошибки-и-исключения-exceptions)
- [Ошибки валидации данных](#ошибки-валидации-данных)
- [Ошибки HTTP](#ошибки-http)
- [Доступный функционал](#доступный-функционал)
- [Способы авторизации](#способы-авторизации)
- [Функции API](#функции-api)
- [Cloudapi](#cloudapi)
- [System](#system)
## Описание
**Dynamix Python SDK** предоставляет удобный интерфейс для интеграции взаимодействия с API **Dynamix Enterprise** в программный код на языке Python.
**Примечание:** проект находится в стадии активной разработки, [доступный функционал](#доступный-функционал) будет расширяться с каждой новой версией.
## Системные требования
### Соответствие версий платформы версиям SDK
| Версия платформы | Версия SDK |
| --- | --- |
| 4.2.0 | 1.0.x |
### Зависимости
Зависимости указаны в конфигурационном файле проекта [pyproject.toml](/pyproject.toml):
- версия Python: раздел `[project]`, ключ `requires-python`
- библиотеки: раздел `[project]`, ключ `dependencies`
**Важно:** использование более поздних версий Python и/или библиотек допустимо, но работоспособность не гарантируется, так как зависит от обратной совместимости с указанными версиями.
## Установка
Установка с помощью системы управления пакетами Python (pip), где `version` - тег с номером версии SDK (см. доступные теги в репозитории):
```sh
pip install git+https://repository.basistech.ru/BASIS/dynamix-python-sdk.git@version
```
Посмотреть версию установленного пакета:
```sh
pip show dynamix-sdk
```
## Использование
### Конфигурация
Для работы с SDK необходимо создать экземпляр класса **Dynamix**, конструктор которого принимает на вход параметры конфигурации SDK.
<details><summary>Авторизация с JWT</summary>
```python
from dynamix_sdk import Dynamix
JWT = '...'
dx = Dynamix(
url='https://...',
auth=JWT,
)
```
</details>
<details><summary>Авторизация через DECS3O</summary>
```python
from dynamix_sdk import Dynamix, DECS3OAuth
dx = Dynamix(
url='https://...',
auth=DECS3OAuth(
url='https://...',
client_id='...',
client_secret='...',
),
)
```
</details>
<details><summary>Авторизация через BVS</summary>
```python
from dynamix_sdk import Dynamix, BVSAuth
dx = Dynamix(
url='https://...',
auth=BVSAuth(
url='https://...',
domain='...',
client_id='...',
client_secret='...',
username='...',
password='...',
),
)
```
</details>
<details><summary>Настройка повторных попыток при 503</summary>
По умолчанию SDK при получении кода ответа 503 производит 10 повторных попыток с интервалом 5 секунд. Данное поведение можно скорректировать:
```python
from dynamix_sdk import Dynamix, DECS3OAuth, BVSAuth
# Для HTTP-запросов к Dynamix
Dynamix(
...,
http503_attempts = 10, # количество повторных попыток при 503
http503_attempts_interval = 5, # интервал в секундах между повторными попытками
)
# Для HTTP-запросов к DECS3O
DECS3OAuth(
...,
http503_attempts = 10, # количество повторных попыток при 503
http503_attempts_interval = 5, # интервал в секундах между повторными попытками
)
# Для HTTP-запросов к BVS
BVSAuth(
...,
http503_attempts = 10, # количество повторных попыток при 503
http503_attempts_interval = 5, # интервал в секундах между повторными попытками
)
```
</details>
<details><summary>Отключение проверки сертификата SSL</summary>
**Важно:** отключение проверки сертификата SSL даёт возможность произвести атаку типа MitM, поэтому пользоваться данной возможостью допустимо только в защищённой среде.
```python
import urllib3
from dynamix_sdk import Dynamix, DECS3OAuth, BVSAuth
urllib3.disable_warnings() # отключение вывода предупреждений безопасности SSL
# Для HTTP-запросов к Dynamix
Dynamix(
...,
verify_ssl=False, # отключение проверки сертификата SSL
)
# Для HTTP-запросов к DECS3O
DECS3OAuth(
...,
verify_ssl=False, # отключение проверки сертификата SSL
)
# Для HTTP-запросов к BVS
BVSAuth(
...,
verify_ssl=False, # отключение проверки сертификата SSL
)
```
</details>
### Функциональный интерфейс
Функциональный интерфейс предоставляет функции, соответствующие функциям API платформы.
#### Вызов функции
<details><summary>Выбор функции, передача параметров и сохранение результата</summary>
![](/demo/select_api_function_and_passing_params_and_save_result.gif)
</details>
<details><summary>Передача вложенных параметров </summary>
```python
from dynamix_sdk import Dynamix, types
dx = Dynamix(...)
data_disk_1 = types.DiskAPIParamsNM(name='data_disk_1', size=10)
# /cloudapi/kvmx86/create
new_vm_id = dx.api.cloudapi.kvmx86.create(
rg_id=123,
name='new_vm',
cpu=1,
ram=1024,
image_id=456,
data_disks=[data_disk_1],
)
```
</details>
<details><summary>Передача параметров перечисляемого типа (enum) </summary>
```python
from dynamix_sdk import Dynamix, types
dx = Dynamix(...)
# /cloudapi/kvmx86/create
new_vm_id = dx.api.cloudapi.kvmx86.create(
rg_id=123,
name='new_vm',
cpu=1,
ram=1024,
image_id=456,
chipset=types.Chipset.Q35, # enum
numa_affinity=types.NumaAffinity.none, # enum
)
```
</details>
#### Результат выполнения функции
Тип данных, возвращаемый функцией API SDK зависит от типа данных, возвращаемого соответствующей функцией API платформы.
Если функция API платформы возвращает структуру данных в виде набора пар ключ/значение (с заранее известными ключами), то функция API SDK возвращает модель Pydantic, которая описывает эту структуру.
<details><summary>Модель</summary>
```python
import pydantic
from dynamix_sdk import Dynamix
dx = Dynamix(...)
# /cloudapi/compute/get
get_result = dx.api.cloudapi.compute.get(compute_id=1)
print(type(get_result)) # <class '....CloudapiComputeGetResultModel'>
print(isinstance(get_result, pydantic.BaseModel)) # True
```
</details>
<details><summary>Обращение к полю модели</summary>
```python
from dynamix_sdk import Dynamix
dx = Dynamix(...)
# /cloudapi/compute/get
vm_name = dx.api.cloudapi.compute.get(compute_id=1).name
```
</details>
Вложенные структуры данных также представлены в виде моделей Pydantic:
<details><summary>Вложенная модель</summary>
```python
import pydantic
from dynamix_sdk import Dynamix
dx = Dynamix(...)
# /cloudapi/compute/get
vm_disk1 = dx.api.cloudapi.compute.get(compute_id=1).disks[0]
print(type(vm_disk1)) # <class '....DiskAPIResultNM'>
print(isinstance(vm_disk1, pydantic.BaseModel)) # True
```
</details>
<details><summary>Обращение к полю вложенной модели</summary>
```python
from dynamix_sdk import Dynamix
dx = Dynamix(...)
# /cloudapi/compute/get
vm_disk1_id = dx.api.cloudapi.compute.get(compute_id=1).disks[0].id
```
</details>
Некоторые поля моделей автоматически генерируются на основе полученных данных от API платформы.<br>
Например, при наличии в модели поля, содержащего временную метку (timestamp), для удобства генерируется поле, содержащее дату и время в виде `datetime`.
<details><summary>Генерируемое поле</summary>
```python
from dynamix_sdk import Dynamix
dx = Dynamix(...)
# /cloudapi/compute/get
get_result = dx.api.cloudapi.compute.get(compute_id=1)
# Поле, возвращаемое платформой
print(type(get_result.created_timestamp)) # <class 'int'>
# Генерируемое поле
print(type(get_result.created_datetime)) # <class 'datetime.datetime'>
```
</details>
Если функция API платформы возвращает примитивный тип данных (строка, число), то функция API SDK возвращает экземпляр класса, наследуемый от класса этого типа данных.
<details><summary>Класс, наследуемый от примитивного типа данных</summary>
```python
from dynamix_sdk import Dynamix
dx = Dynamix(...)
# /cloudapi/kvmx86/create
new_vm_id = dx.api.cloudapi.kvmx86.create(...)
print(type(new_vm_id)) # <class '....CloudapiKvmx86CreateResultInt'>
print(isinstance(new_vm_id, int)) # True
```
</details>
Исключением является булев тип данных. Так как наследование от класса `bool` в Python недопустимо, функция API SDK возвращает экземпляр класса, который обладает функциональностью для использования в булевых выражениях (реализован метод `__bool__`), но само булево значение хранится в атрибуте `value`:
<details><summary>Класс с булевым значением</summary>
```python
from dynamix_sdk import Dynamix
dx = Dynamix(...)
# /cloudapi/compute/delete
delete_result = dx.api.cloudapi.compute.delete(compute_id=1)
print(type(delete_result)) # <class '....CloudapiComputeDeleteResultBool'>
print(type(delete_result.value)) # <class 'bool'>
```
Использование в булевом выражении:
```python
from dynamix_sdk import Dynamix
dx = Dynamix(...)
# /cloudapi/compute/delete
if dx.api.cloudapi.compute.delete(compute_id=1):
print('The VM has been deleted.')
```
</details>
Все объекты, возвращаемые функциями API SDK, обладают общими специальными атрибутами:
| Атрибут | Описание |
| --- | --- |
| `_api_params` | Модель Pydantic, описывающая параметры, переданные в функцию. |
| `_http_response` | HTTP-ответ API платформы в виде экземпляра класса `requests.Response`. |
#### Соответствие названий
В SDK названия из API платформы приведены к стилю "snake_case", принятому в Python, а в некоторых случаях имеют иные отличия, при этом сохраняя смысл исходного названия в API платформы.
Для соответствия названий в SDK используются таблицы соответствия, с помощью которых можно узнать исходное название в API платформы.
<br>Каждая такая таблица хранится в виде словаря в файле YAML:
- [api/path_mapping.yml](/src/dynamix_sdk/api/path_mapping.yml) - таблица соответствия названий частей маршрута (URL path) к функции API.
<br>Данная таблица содержит только те названия, которые отличаются от названий в API платформы.
- [api/name_mapping.yml](/src/dynamix_sdk/api/name_mapping.yml) - таблица соответствия названий параметров функций и полей возвращаемых данных.
<br>Данная таблица содержит все названия, в том числе и те, которые совпадают с названиями в API платформы.
<br>Кроме общих соответствий, данная таблица также содержит индивидуальные соответствия, которые применяются только к классу модели, указанному в формате `sdk_name__model_class_name`.
### Типы данных SDK
Все типы данных (классы) SDK, которые могут пригодиться при разработке ПО с использованием SDK, доступны через модуль `dynamix_sdk.types`.
### Ошибки и исключения (exceptions)
SDK может вызывать исключения, которые должны быть обработаны в соответствии с требованиями к разрабатываемому вами ПО.
#### Ошибки валидации данных
SDK производит валидацию параметров функций API с помощью библиотеки **Pydantic**.<br>
Поэтому, при ошибке валидации, будет вызвано исключение `pydantic.ValidationError`.
Таким же образом валидируются данные HTTP-ответов API платформы. Причиной ошибки валидации данных HTTP-ответа API платформы может быть:
1. Несоответствие версии SDK и версии платформы.
1. Программная ошибка, допущенная при разработке SDK или платформы. Получить подтверждение наличия такой ошибки, а также ускорить её устранение, можно сообщив о ней.
Получить подробную информацию об исключении `pydantic.ValidationError` можно [в соответствующем разделе официальной документации Pydantic](https://docs.pydantic.dev/latest/errors/errors/) (ссылка ведёт на документацию для последней версии, поэтому важно выбрать версию, соответствующую используемой в SDK).
#### Ошибки HTTP
SDK для выполнения HTTP-запросов использует библиотеку **Requests**.<br>
Поэтому, при ошибке HTTP-подключения, будет вызвано соответствующее исключение библиотеки **Requests**.
Для проверки соответствует ли код ответа успешному выполнению запроса, SDK вызывает метод `requests.Response.raise_for_status()`, поэтому при неуспешном HTTP-запросе также будет вызвано исключение библиотеки **Requests**.
**Примечание:** если код ответа 503, то SDK предпримет несколько повторных попыток. Подробнее в разделе [Конфигурация](#конфигурация).
<details><summary>Обработка ошибок HTTP</summary>
```python
from requests.exceptions import RequestException, HTTPError
from dynamix_sdk import Dynamix
dx = Dynamix(...)
vm_id = 1
try:
get_result = dx.api.cloudapi.compute.get(compute_id=vm_id)
except HTTPError as e:
resp = e.response
if resp.status_code == 404:
print(f'The VM ID={vm_id} not found.')
else:
print(f'{e}: {resp.text}')
except RequestException as e:
print(e)
```
</details>
Подробную информацию об исключениях библиотеки **Requests** можно получить в [соответствующем разделе официальной документации Requests](https://requests.readthedocs.io/en/latest/user/quickstart/#errors-and-exceptions).
## Доступный функционал
### Способы авторизации
- с JWT
- через DECS3O
- через BVS
Подробнее в разделе [Конфигурация](#конфигурация).
### Функции API
#### Cloudapi
<details><summary>account</summary>
- /cloudapi/account/addUser
- /cloudapi/account/deleteUser
- /cloudapi/account/disable
- /cloudapi/account/enable
- /cloudapi/account/updateUser
</details>
<details><summary>compute</summary>
- /cloudapi/compute/delete
- /cloudapi/compute/get
- /cloudapi/compute/list
- /cloudapi/compute/update
</details>
<details><summary>kvmx86</summary>
- /cloudapi/kvmx86/create
</details>
<details><summary>rg</summary>
- /cloudapi/rg/create
- /cloudapi/rg/get
- /cloudapi/rg/list
</details>
<details><summary>user</summary>
- /cloudapi/user/get
</details>
#### System
<details><summary>usermanager</summary>
- /system/usermanager/whoami
</details>