Files
de-py-sdk/README.md
2026-10-30 16:27:40 +03:00

357 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.
<details><summary>Авторизация</summary>
```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)
```
</details>
<details><summary>Задание декораторов для всех вызываемых функций</summary>
```python
from digital_energy_sdk import DigitalEnergy
DigitalEnergy(
...,
f_decorators=[decorator_1, decorator_2],
)
```
Декораторы будут применяться к вызываемым функциям SDK в обратном порядке, то есть сначала будет применяться декоратор <code>decorator_2</code>, а потом <code>decorator_1</code>.
**Важно:** декораторы должны соответствовать аннотации параметра, то есть оставлять без изменений параметры и тип возвращаемого значения функции, иначе применение декораторов приведёт к некорректной работе SDK.
</details>
<details><summary>Настройка повторных попыток при 503</summary>
По умолчанию SDK при получении кода ответа 503 производит 10 повторных попыток с интервалом 5 секунд. Данное поведение можно скорректировать:
```python
from digital_energy_sdk import DigitalEnergy
DigitalEnergy(
...,
http503_attempts = 10, # количество повторных попыток при 503
http503_attempts_interval = 5, # интервал в секундах между повторными попытками
)
```
</details>
<details><summary>Отключение проверки сертификата SSL</summary>
**Важно:** отключение проверки сертификата SSL даёт возможность произвести атаку типа MitM, поэтому пользоваться данной возможостью допустимо только в защищённой среде.
```python
import urllib3
from digital_energy_sdk import DigitalEnergy
urllib3.disable_warnings() # отключение вывода предупреждений безопасности SSL
DigitalEnergy(
...,
verify_ssl=False, # отключение проверки сертификата SSL
)
```
</details>
### Функциональный интерфейс
Функциональный интерфейс предоставляет функциональные объекты, каждый из которых является реализацией соответствующей функции API. Для упрощения изложения в данном руководстве вместо термина **функциональный объект** будет использоваться термин **функция**, если это позволяет контекст.
#### Вызов функции
<details><summary>Выбор функции, передача параметров и сохранение результата</summary>
```python
from digital_energy_sdk import DigitalEnergy
de = DigitalEnergy(...)
# /digitalenergy/cluster/get
result = de.api.digitalenergy.cluster.get(id=1)
```
</details>
<details><summary>Передача параметров перечисляемого типа (enum) </summary>
```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)
```
</details>
<details><summary>Передача файловых параметров </summary>
```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,
)
)
```
</details>
#### Результат выполнения функции
Тип данных, возвращаемый функцией SDK зависит от типа данных, возвращаемого соответствующей функцией API.
Если в результате функции API присутствует структура данных в виде набора пар ключ/значение с заранее известными ключами, то в результате функции SDK эта структура будет представлена в виде модели Pydantic. Остальные типы данных будут представлены соответствующими встроенными типами данных Python.
<details><summary>Модель</summary>
```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)) # <class '....DigitalenergyClusterListResult'>
print(isinstance(list_result, pydantic.BaseModel)) # True
```
</details>
<details><summary>Обращение к полю модели</summary>
```python
from digital_energy_sdk import DigitalEnergy
de = DigitalEnergy(...)
# /digitalenergy/cluster/list
clusters = de.api.digitalenergy.cluster.list().result.clusters
```
</details>
<details><summary>Вложенная модель</summary>
```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)) # <class '....ClustersItem'>
print(isinstance(cluster1, pydantic.BaseModel)) # True
```
</details>
<br>Все функциональные объекты, реализующие функции API, обладают следующими атрибутами:
| Атрибут | Описание |
| --- | --- |
| `api_path` | API URL path. |
| `config` | Экземпляр конфигурации SDK. |
| `func_name` | Название функции SDK в формате <code>digitalenergy.cluster.list</code> |
| `http_method` | HTTP-метод. |
| `last_http_resp` | Экзепляр класса <code>requests.Response</code>, полученный при последнем вызове ФО. |
| `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**.<br>
Поэтому, при ошибке валидации, будет вызвано исключение `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**.<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 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)
```
</details>
Подробную информацию об исключениях библиотеки **Requests** можно получить в [соответствующем разделе официальной документации Requests](https://requests.readthedocs.io/en/latest/user/quickstart/#errors-and-exceptions).
<details><summary>Использование исключения SDK</summary>
Для возможности получать дополнительную информацию о функциях SDK при ошибках HTTP-запросов, в SDK есть возможность оборачивать все исключения <code>requests.exceptions.RequestException</code> в исключение <code>digital_energy_sdk.exceptions.RequestException</code>:
```python
class RequestException(Exception):
orig_exception: requests.exceptions.RequestException
func_name: str
func_kwargs: None | dict = None
status_code: None | int = None
```
Чтобы включить использование исключения <code>digital_energy_sdk.exceptions.RequestException</code>, необходимо передать в конструктор класса <code>DigitalEnergy</code> параметр <code>wrap_request_exceptions=True</code>
</details>
## Доступная функциональность
На данный момент в SDK доступна реализация всех функций API, за исключением:
- `/openid/{providername}/authenticate`
- `/digitalenergy/istore/charts/download`
- `/digitalenergy/istore/icon/download`
- `/digitalenergy/istore/image/download`
- `/digitalenergy/lrecords/download`
- `/digitalenergy/cluster/getKubectlResources`