# Digital Energy Python SDK - [Описание](#описание) - [Системные требования](#системные-требования) - [Установка](#установка) - [Использование](#использование) - [Конфигурация](#конфигурация) - [Функциональный интерфейс](#функциональный-интерфейс) - [Вызов функции](#вызов-функции) - [Результат выполнения функции](#результат-выполнения-функции) - [Соответствие названий](#соответствие-названий) - [Типы данных SDK](#типы-данных-sdk) - [Ошибки и исключения (exceptions)](#ошибки-и-исключения-exceptions) - [Ошибки валидации данных](#ошибки-валидации-данных) - [Ошибки HTTP](#ошибки-http) - [Доступная функциональность](#доступная-функциональность) ## Описание **Digital Energy Python SDK** предоставляет удобный интерфейс для интеграции взаимодействия с API **Digital Energy** в программный код на языке Python. ## Системные требования ### Совместимость версий **Digital Energy** и версий SDK | Digital Energy | SDK | | --- | --- | | 1.9.0 | 2.0.x | | 1.8.0 | 1.0.x | ### Зависимости Зависимости указаны в конфигурационном файле проекта [pyproject.toml](/pyproject.toml): - версия Python: раздел `[project]`, ключ `requires-python` - библиотеки: раздел `[project]`, ключ `dependencies` ## Установка Установка с помощью системы управления пакетами Python (pip), `version` - тег или ветка: ```sh pip install git+https://repository.basistech.ru/BASIS/de-py-sdk@version ``` Посмотреть версию установленного пакета: ```sh pip show digital_energy_sdk ``` ## Использование ### Конфигурация Для работы с SDK необходимо создать экземпляр класса `DigitalEnergy`, конструктор которого принимает на вход параметры конфигурации SDK.
Авторизация ```python from digital_energy_sdk import DigitalEnergy DE_URL = '...' USERNAME = '...' PASSWORD = '...' token = DigitalEnergy( url=DE_URL, auth='', ).api.session.create( username=USERNAME, password=PASSWORD, ).result.token de = DigitalEnergy(url=DE_URL, auth=token) ```
Задание декораторов для всех вызываемых функций ```python from digital_energy_sdk import DigitalEnergy DigitalEnergy( ..., f_decorators=[decorator_1, decorator_2], ) ``` Декораторы будут применяться к вызываемым функциям SDK в обратном порядке, то есть сначала будет применяться декоратор decorator_2, а потом decorator_1. **Важно:** декораторы должны соответствовать аннотации параметра, то есть оставлять без изменений параметры и тип возвращаемого значения функции, иначе применение декораторов приведёт к некорректной работе SDK.
Настройка повторных попыток при 503 По умолчанию SDK при получении кода ответа 503 производит 10 повторных попыток с интервалом 5 секунд. Данное поведение можно скорректировать: ```python from digital_energy_sdk import DigitalEnergy DigitalEnergy( ..., http503_attempts = 10, # количество повторных попыток при 503 http503_attempts_interval = 5, # интервал в секундах между повторными попытками ) ```
Отключение проверки сертификата SSL **Важно:** отключение проверки сертификата SSL даёт возможность произвести атаку типа MitM, поэтому пользоваться данной возможостью допустимо только в защищённой среде. ```python import urllib3 from digital_energy_sdk import DigitalEnergy urllib3.disable_warnings() # отключение вывода предупреждений безопасности SSL DigitalEnergy( ..., verify_ssl=False, # отключение проверки сертификата SSL ) ```
### Функциональный интерфейс Функциональный интерфейс предоставляет функциональные объекты, каждый из которых является реализацией соответствующей функции API. Для упрощения изложения в данном руководстве вместо термина **функциональный объект** будет использоваться термин **функция**, если это позволяет контекст. #### Вызов функции
Выбор функции, передача параметров и сохранение результата ```python from digital_energy_sdk import DigitalEnergy de = DigitalEnergy(...) # /digitalenergy/cluster/get result = de.api.digitalenergy.cluster.get(id=1) ```
Передача параметров перечисляемого типа (enum) ```python from digital_energy_sdk import DigitalEnergy from digital_energy_sdk.api.digitalenergy.cluster.list import Type de = DigitalEnergy(...) # /digitalenergy/cluster/list list_result = de.api.digitalenergy.cluster.list(type=Type.DENERGY) ```
Передача файловых параметров ```python from digital_energy_sdk import DigitalEnergy from digital_energy_sdk.types.params import ParamFile de = DigitalEnergy(...) file_name = ... with open(file_name, 'rb') as f: # /digitalenergy/files/fileUpload de.api.digitalenergy.files.file_upload( file=ParamFile( file_name=file_name, content=f, ) ) ```
#### Результат выполнения функции Тип данных, возвращаемый функцией SDK зависит от типа данных, возвращаемого соответствующей функцией API. Если в результате функции API присутствует структура данных в виде набора пар ключ/значение с заранее известными ключами, то в результате функции SDK эта структура будет представлена в виде модели Pydantic. Остальные типы данных будут представлены соответствующими встроенными типами данных Python.
Модель ```python import pydantic from digital_energy_sdk import DigitalEnergy de = DigitalEnergy(...) # /digitalenergy/cluster/list list_result = de.api.digitalenergy.cluster.list() print(type(list_result)) # print(isinstance(list_result, pydantic.BaseModel)) # True ```
Обращение к полю модели ```python from digital_energy_sdk import DigitalEnergy de = DigitalEnergy(...) # /digitalenergy/cluster/list clusters = de.api.digitalenergy.cluster.list().result.clusters ```
Вложенная модель ```python import pydantic from digital_energy_sdk import DigitalEnergy de = DigitalEnergy(...) # /digitalenergy/cluster/list cluster1 = de.api.digitalenergy.cluster.list().result.clusters[0] print(type(cluster1)) # print(isinstance(cluster1, pydantic.BaseModel)) # True ```

Все функциональные объекты, реализующие функции API, обладают следующими атрибутами: | Атрибут | Описание | | --- | --- | | `api_path` | API URL path. | | `config` | Экземпляр конфигурации SDK. | | `func_name` | Название функции SDK в формате digitalenergy.cluster.list | | `http_method` | HTTP-метод. | | `last_http_resp` | Экзепляр класса requests.Response, полученный при последнем вызове ФО. | | `last_params_model` | Модель Pydantic, содержащая параметры, переданные в последний вызов ФО. | | `params_model_type` | Класс модели Pydantic для параметров вызова ФО. | | `post_json` | Отправляются ли данные в формате JSON в POST-запросах. | | `result_type` | Аннотация типа результата вызова ФО. | | `signature` | Сигнатура вызова ФО. | #### Соответствие названий В SDK названия из API приведены к стилю, принятому в Python: - PascalCase для названия классов - snake_case для названия атрибутов классов (кроме классов перечисляемых типов) - SCREAMING_CASE для названия атрибутов классов перечисляемых типов ### Типы данных SDK Общие типы доступны через пакет `digital_energy_sdk.types`. Частные типы доступны через модуль функции. Например, частные типы функции `digitalenergy.cluster.list` расположены в модуле `digital_energy_sdk.api.digitalenergy.cluster.list`. ### Ошибки и исключения (exceptions) SDK может вызывать исключения, которые должны быть обработаны в соответствии с требованиями к разрабатываемому вами ПО. #### Ошибки валидации данных SDK производит валидацию параметров функций API с помощью библиотеки **Pydantic**.
Поэтому, при ошибке валидации, будет вызвано исключение `pydantic.ValidationError`. Таким же образом валидируются данные HTTP-ответов API. Причиной ошибки валидации данных HTTP-ответа API может быть: 1. Несоответствие версии SDK и версии **Digital Energy**. 1. Программная ошибка, допущенная при разработке SDK или **Digital Energy**. Получить подтверждение наличия такой ошибки, а также ускорить её устранение, можно сообщив нам о ней. Получить подробную информацию об исключении `pydantic.ValidationError` можно [в соответствующем разделе официальной документации Pydantic](https://docs.pydantic.dev/latest/errors/errors/) (ссылка ведёт на документацию для последней версии, поэтому важно выбрать версию, соответствующую используемой в SDK). #### Ошибки HTTP SDK для выполнения HTTP-запросов использует библиотеку **Requests**.
Поэтому, при ошибке HTTP-подключения, будет вызвано соответствующее исключение библиотеки **Requests**. Для проверки соответствует ли код ответа успешному выполнению запроса, SDK вызывает метод `requests.Response.raise_for_status()`, поэтому при неуспешном HTTP-запросе также будет вызвано исключение библиотеки **Requests**. **Примечание:** если код ответа 503, то SDK предпримет несколько повторных попыток. Подробнее в разделе [Конфигурация](#конфигурация).
Обработка ошибок HTTP ```python from requests.exceptions import RequestException, HTTPError from digital_energy_sdk import DigitalEnergy cluster_id = 1 try: get_result = de.api.digitalenergy.cluster.get(id=cluster_id) except HTTPError as e: resp = e.response if resp.status_code == 404: print(f'The cluster with ID={cluster_id} not found.') else: print(f'{e}: {resp.text}') except RequestException as e: print(e) ```
Подробную информацию об исключениях библиотеки **Requests** можно получить в [соответствующем разделе официальной документации Requests](https://requests.readthedocs.io/en/latest/user/quickstart/#errors-and-exceptions).
Использование исключения SDK Для возможности получать дополнительную информацию о функциях SDK при ошибках HTTP-запросов, в SDK есть возможность оборачивать все исключения requests.exceptions.RequestException в исключение digital_energy_sdk.exceptions.RequestException: ```python class RequestException(Exception): orig_exception: requests.exceptions.RequestException func_name: str func_kwargs: None | dict = None status_code: None | int = None ``` Чтобы включить использование исключения digital_energy_sdk.exceptions.RequestException, необходимо передать в конструктор класса DigitalEnergy параметр wrap_request_exceptions=True
## Доступная функциональность На данный момент в SDK доступна реализация всех функций API, за исключением: - `/openid/{providername}/authenticate` - `/digitalenergy/istore/charts/download` - `/digitalenergy/istore/icon/download` - `/digitalenergy/istore/image/download` - `/digitalenergy/lrecords/download` - `/digitalenergy/cluster/getKubectlResources`