Конфигурация и метаданные пользовательского интерфейса
Область применения: все объявления конфигурации, наследующие
BaseConfig/BotAccountConfig(глобальные настройки адаптера, настройки аккаунта, настройки модуля).
Система конфигурации ErisPulse является декларативной: разработчики описывают параметры конфигурации с помощью полей dataclass и метаданных, а фреймворк get_config_schema() преобразует их в JSON Schema, который может быть использован любым потребителем (панель управления, сторонняя панель, CLI-модуль и т.д.) для отображения. В этой статье приведено нормативное определение этих метаданных — семантика виджетов, форма значений, условия отображения и обязательства по совместимости определяются исключительно здесь; конкретная реализация за потребителями, но семантика должна соответствовать этой статье.
Структура объявления
from dataclasses import dataclass, field
from ErisPulse.Core.Bases import BaseConfig, BotAccountConfig
@dataclass
class MyAdapterConfig(BaseConfig):
"""Глобальная конфигурация адаптера"""
@dataclass
class MyAccountConfig(BotAccountConfig):
"""Конфигурация аккаунта (адаптер с несколькими аккаунтами)"""
token: str = field(
default="",
metadata={
"description": "Токен доступа",
"required": True,
"secret": True,
"ui": {
"widget": "password",
"group": "basic",
"order": 1,
"placeholder": "Вставьте токен платформы",
},
},
)
Основные метаданные (ключи верхнего уровня metadata)
| Ключ | Тип | Семантика |
|---|---|---|
description |
str или {"i18n": ключ, "default": текст} |
Описание параметра (поддержка ссылок на i18n) |
required |
bool |
Обязательный (валидация и подсказка в UI; если обязательное поле аккаунта пустое, при оплате можно уведомить, что конфигурация не завершена) |
secret |
bool |
Сенсорное значение: в UI должно отображаться как пароль, маскировка в логах |
UI-метаданные (подтаблица metadata["ui"])
Ключ ui является стандартным; webui — это старое алиас (эквивалентно, потребители должны поддерживать оба).
Общие ключи
| Ключ | Семантика |
|---|---|
widget |
Тип виджета (см. список виджетов); если отсутствует, выводится по типу поля |
group |
Название группы; отображаемое имя для групп с одинаковым названием предоставляется в _schema_meta["group_labels"] (также поддерживается словарь i18n) |
order |
Вес сортировки внутри группы (меньшее значение — выше, по умолчанию 100) |
options |
Элементы перечисления [{label, value}] (label поддерживает словарь i18n; используется для select/multiselect) |
placeholder |
Текст-заполнитель (поддерживается словарь i18n) |
min / max / step |
Диапазон и шаг (number/slider) |
rows |
Количество строк для многострочного текста (textarea) |
Условное отображение/отключение (взаимосвязь полей)
| Ключ | Семантика |
|---|---|
show_if |
При невыполнении условия поле скрывается (значение сохраняется, не удаляется) |
disabled_if |
При выполнении условия поле отключается (делается серым и заблокированным, значение сохраняется) |
Объект условия: {"field": <имя поля или полный ключ конфигурации в том же диапазоне>, "op": <оператор>, "value": <сравниваемое значение>}. Набор операторов:
| op | Семантика |
|---|---|
eq / ne |
Равно / не равно (сравнение после преобразования в строку) |
in / nin |
value — массив, является элементом / не является элементом |
gt / gte / lt / lte |
Числовое сравнение |
truthy |
Истинное значение (не пустое, не "false", не "0") |
Если op не указан, по умолчанию используется eq. Разбор поля: сначала по короткому имени в том же диапазоне конфигурации, затем по полному ключу (например, accounts.default.mode).
Формат значения (value_type, используется для multiselect)
| Значение | Формат хранения | Применение |
|---|---|---|
json (по умолчанию) |
JSON-массив в виде строки (например, "[0, 25]") |
Тип поля str, массив хранится в виде JSON-строки |
array |
Оригинальный массив | Тип поля list |
mask |
Целочисленный битовый маска (выбираемые значения суммируются как 2^v) |
Тип поля int для битовых флагов, options[].value — номер бита |
Обязанности потребителя: Если value_type не указан, необходимо определять по типу поля (если int и цифровые опции → mask; если list → array; в остальных случаях → json), чтобы при объявлении только widget: multiselect можно было корректно записывать значения нужного типа.
Справочник виджетов
Потребитель должен реализовать следующую семантику; неизвестные виджеты должны возвращаться к однорядному тексту, без ошибок.
| Виджет | Тип значения | Семантика |
|---|---|---|
text |
str | Однорядный текст (по умолчанию, целевой виджет для возврата) |
textarea |
str | Многострочный текст (rows) |
password |
str | Пароль (secret: True автоматически определяется) |
number |
int/float | Ввод чисел (min/max/step; автоматически определяется для полей числового типа) |
switch |
bool | Переключатель (bool автоматически определяется для поля bool) |
select |
str | Одиночный выпадающий список (options; автоматически определяется для строковых полей с options) |
multiselect |
См. тип значения | Множественный выбор (группа флажков; options + value_type) |
slider |
int/float | Ползунок (min/max/step) |
color |
str | Цвет (#rrggbb) |
date / time / datetime |
str | Дата / Время / Дата и время (строка в формате ISO) |
kv |
dict | Редактор пар ключ-значение (dict[str, str]) |
list |
list | Редактор списка (item объявляет вложенные поля: {"widget": ...} или {"fields": {...}} поддерживает вложенные в строки) |
Контракт совместимости (должен соблюдаться потребителями)
- Игнорировать неизвестные ключи: при появлении в метаданных ключей, не описанных в спецификации (включая будущие добавления), игнорировать их без ошибки.
- Вернуться к text для неизвестного widget: обеспечить, чтобы новые объявления оставались редактируемыми на старых потребителях.
- Условие не выполнено ≠ удаление значения: значения полей, скрытых через
show_if, сохраняются без изменений. - Типизация по умолчанию: при отсутствии расширенных ключей, таких как
value_type, корректно определять форму хранения на основе типа поля.
Полный пример
@dataclass
class OneBotAccountDemo(BotAccountConfig):
mode: str = field(
default="server",
metadata={
"description": "Режим подключения",
"ui": {
"widget": "select",
"group": "connection",
"order": 1,
"options": [
{"label": "Server (пассивный)", "value": "server"},
{"label": "Client (активный)", "value": "client"},
],
},
},
)
url: str = field(
default="ws://127.0.0.1:3001",
metadata={
"description": "Адрес WebSocket",
"ui": {
"widget": "text",
"group": "connection",
"order": 2,
"show_if": {"field": "mode", "op": "eq", "value": "client"},
},
},
)
intents: int = field(
default=33281,
metadata={
"description": "Маска битов (поле типа int, автоматически хранится по маске)",
"ui": {
"widget": "multiselect",
"group": "advanced",
"order": 3,
"options": [
{"label": "Основа каналов", "value": 0},
{"label": "Сообщения каналов", "value": 9},
{"label": "Содержание сообщений (привилегии)", "value": 15},
],
},
},
)
Схема вывода
ErisPulse.Core.Bases.config_schema.get_config_schema(cls) выводит JSON-схему (поля/группы/account_based/метаданные), и прозрачно передает все ключи подтаблицы ui, определённые в настоящем документе, для прямого использования потребителями.