ym88659208ym87991671
Базовые классы | Документация для разработчиков
Skip to main content

Базовые классы

Обновлено 13 октября 2022

SmartApp Framework позволяет изменить поведение базовых классов путем наследования. Это необязательная опция, которая позволяет внести изменения в функциональность смартапа.

Для расширения фреймворка необходимо:

  1. Создать наследника от класса.
  2. Добавить новую функциональность, которой нет в базовом классе.
  3. Зарегистрировать новый класс в app_config.

Ниже перечислены основные базовые классы, от которых можно создать наследника.

BaseMainLoop — цикл обработки сообщений

BaseMainLoop — является базовым классом, который реализует рабочий цикл обработки сообщений от пользователя. Создав наследника от этого класса, можно переопределить следующие методы:

def run(self)

Метод, в котором реализуется цикл работы смартапа.

def stop(self, signum, frame)

Метод для остановки выполнения метода run.

def load_user(self, db_uid, message)

Метод загрузки текущего состояния пользователя из используемой БД. В качестве результата ожидается получение экземпляра класса User или производной от этого класса.

Метод имеет следующие объекты:

  • db_uid — уникальный идентификатор, по которому хранится запись о состоянии пользователя в БД;
  • message — входящее сообщение от пользователя. Объект класса FromMessage или наследника от него.
def save_user(self, db_uid, user, message)

Метод сохранения состояния пользователя в БД. В качестве результата ожидается получение bool флага, который отражает, произошла ли коллизия записи в БД (т.е. при сохранении обнаружено, что данные уже были кем-то изменены).

Метод имеет следующие объекты:

  • db_uid — уникальный идентификатор, по которому хранится запись о состоянии пользователя в БД;
  • user — объект класса User или производный от этого класса;
  • message — входящее сообщение от пользователя. Объект класса FromMessage или наследника от него.
def _generate_answers(self, user, commands, message, **kwargs)

Метод для создания объектов ответов от смартапа к пользователю. Используется внутри MainLoop для дополнительной работы объектов Command. Предполагается, что внутри будут созданы объекты класса SmartKitKafkaReqeust / RestRequest или другой пользовательский тип запроса. На основании объектов Command, message, request будет создан объект класса SmartAppToMessage. В качестве результата ожидается получение списка объектов класса SmartAppToMessage.

Метод имеет следующие объекты:

  • user — объект класса User или производный от этого класса;
  • commands — list объектов класса Command (например, обогащение, изменение, удаление полей);
  • message — входящее сообщение от пользователя. Объект класса FromMessage или наследника от него;
  • **kwargs — дополнительные именованные аргументы.

SmartAppModel — обработка сообщения

SmartAppModel — является базовым классом, который обрабатывает входящее сообщение и возвращает ответ на него обратно в MainLoop.

Внутри конструктора можно переопределить маппинг MessageName:Handler, за который отвечает переменная self._handlers. Сейчас в этой переменной определяются обработчики сообщений следующего типа:

  • MESSAGE_TO_SKILL,
  • RUN_APP,
  • LOCAL_TIMEOUT,
  • SERVER_ACTION,
  • CLOSE_APP.

Создав наследника от класса SmartAppModel, можно переопределить следующие методы:

def __init__(self, resources: SmartAppResources, dialogue_manager_cls, custom_settings, **kwargs)
@exc_handler(on_error_obj_method_name="on_answer_error")

Декоратор для ошибок во время обработки входящего сообщения внутри метода answer.

def answer(self, message, user)

Метод, в котором выбирается и вызывается обработчик в зависимости от типа входящего сообщения. В качестве результата ожидается list объектов класса Command, которые в дальнейшем будут использоваться в методе _generate_answers внутри MainLoop.

Метод имеет следующие объекты:

  • message — входящее сообщение от пользователя. Объект класса FromMessage или наследника от него;
  • user — объект класса User или производный от этого класса.
def on_answer_error(self, message, user)

Метод, который вызывается в случае ошибки внутри метода answer.

Метод имеет следующие объекты:

  • message — входящее сообщение от пользователя. Объект класса FromMessage или наследника от него;
  • user — объект класса User или производный от этого класса.
def get_handler(self, message_type)

Логика выбора обработчика для сообщения в зависимости от типа сообщения. Тип входящего сообщения передается в message_type. В качестве результата ожидается объект класса HandlerBase или его наследник.

HandlerBase — обработка сообщений по типам

HandlerBase — базовый класс для обработчиков, в которых реализована различная логика обработки определенного типа сообщения. Создав наследника от класса HandlerBase, можно переопределить следующие методы:

def __init__(self, app_name)

app_name — название созданного смартапа. Используется внутри HandlerBase для мониторинга.

def run(self, payload, user)

В качестве результата работы метода ожидается list объектов класса Command, которые в дальнейшем будут использоваться в методе _generate_answers внутри MainLoop.

Метод имеет следующие объекты:

  • payload — поле payload, которое можно получить из объекта класса FromMessagemessage.payload;
  • user — объект класса User или производный от этого класса.

DialogueManager — работа со сценариями

DialogueManager — базовый класс, который на основании интента из message.payload выбирает и запускает новый сценарий или продолжает работу текущего. Создав наследника от класса DialogueManager, можно переопределить следующие методы:

def __init__(self, scenario_descriptions, app_name, **kwargs)
  • scenario_descriptions — json-файлы, загруженные в память из папки referenses: сценарии, формы, actions, requirements и т.д. Метод нужен для получения актуального списка сценариев;
  • app_name — название созданного смартапа. Используется внутри DialogueManager для мониторинга;
  • **kwargs — дополнительные именованные аргументы.
def _nothing_found_action(self)

Метод выполняется, когда входящее сообщение не подходит текущему запущенному сценарию. Например, пользователь спросил что-то другое.

В этом случае, если на основе входящего сообщения ни одно поле формы не может быть заполнено, срабатывает NOTHING_FOUND action, который возвращает соответствующее сообщение ассистенту. Как результат работы, ожидается объект класса Action.

def run(self, text_preprocessing_result, user)

Метод запуска работы сценария на основе интента из входящего сообщения. Предполагается, что внутри этого метода будет выбран сценарий и запущен метод run_scenario для обработки выбранного сценария.

Метод имеет следующие объекты:

  • text_preprocessing_result — объект класса TextPreprocessingResult, который получается на основе поля payload.message из входящего сообщения;
  • user — объект класса User или производный от этого класса.
def run_scenario(self, scen_id, text_preprocessing_result, user)

Метод запуска и получения результатов от выбранного сценария на основе входящего сообщения. В качестве результата работы методы ожидается list объектов класса Command, которые в дальнейшем будут использоваться в методе _generate_answers внутри MainLoop. Список может быть пустой.

Метод имеет следующие объекты:

  • scen_id — id сценария из коллекции scenario_descriptions['scenarios'];
  • text_preprocessing_result — объект класса TextPreprocessingResult, который получается на основе поля payload.message из входящего сообщения;
  • user — объект класса User или производный от этого класса.

SmartAppResources — регистрация сущностей

SmartAppResources — класс, который используется для загрузки ресурсов из json и регистрации базовых сущностей: actions, requirements, fillers и т.д. в соответствующих фабриках. Создав наследника от класса SmartAppResources, можно переопределить следующие методы:

def _subfolder(self)

Свойство для указания папки, из которой будут загружаться ресурсы.

def override_repositories(self, repositories: list)

Метод предназначен для добавления новых репозиториев в дочерних классах. На выходе ожидается дополненный список repositories с новыми сущностями, которые характерны для конкретного смартапа.

Метод имеет следующие объекты:

  • repositories — список репозиториев класса SmartAppResources.
def init(self)

Метод, в котором подряд запускаются методы для добавления новых сущностей в соответствующие фабрики.

def init_field_filler_description(self)

Метод регистрации новых филлеров. Например:

import scenarios.scenario_models.field.field_filler_description as ffd

def init_field_filler_description(self):
super(CustomAppResourses, self).init_field_filler_description()

где ffd.field_filler_description — фабрика филлеров.

def init_actions(self)

Метод регистрации новых actions. Например:

from core.basic_models.actions.basic_actions import actions

def init_actions(self):
  super(CustomAppResourses, self).init_actions()
  actions["simple_action"] = SamlpeAction

где actions — фабрика actions.

def init_requirements(self)

Метод регистрации новых requirements. Например:

from core.basic_models.requirement.basic_requirements import requirements

def init_requirements(self):
  super(CustomAppResourses, self).init_requirements()
  requirements["sample_requirement"] = SampleRequirement

где requirements — фабрика requirements.

def init_db_adapters(self)

Методы регистрации новых адаптеров для БД. Например:

from core.db_adapter.db_adapter import db_adapters

def init_db_adapters(self):

  super(CustomAppResourses, self).init_db_adapters()
  db_adapters["custom_db_adapter"] = CustomDBAdapter

где db_adapters — фабрика адаптеров.

BaseUser — состояние пользователя

В SmartApp Framework реализован класс BaseUser и его наследник User, которые описывают состояние пользователя:

  • Если есть необходимость иметь максимально собственный класс для хранения состояний пользователя, без использования полей для корректной работы сценарной логики, то рекомендуется делать наследника от класса BaseUser.
  • Если нужна сценарная логика и нужно добавить новые поля, то рекомендуется делать наследника от класса User.  Создав наследника от класса, можно переопределить следующие методы:
@lazy
def parametrizer(self)

Свойство, которое возвращает объект класса BasicParametrizer или его наследников.

@property
def fields(self)

Свойство, которое возвращает список объектов класса Field, являющиеся свойствами пользователя

@property
def raw(self)

Свойство, которое возвращает словарь типа {field.name: {"field.attr1":..}, ...}

@property
def raw_str(self)

Свойство, которое возвращает json представление словаря из метода raw. Используется для сохранения пользователя в БД.

def expire(self)

Метод, в котором последовательно вызываются expire от Field класса User. Используется для очистки данных, которые уже потеряли со временем свою актуальность для пользователя.

BasicParametrizer — сборка словаря

BasicParametrizer — класс, который собирает словарь из различных доступных объектов системы: User, Settings, Forms и т.д., чтобы использовать данные при рендеренге jinja-шаблона. Создав наследника от класса, можно переопределить следующие методы:

def collect(self, text_preprocessing_result=None, filter_params=None)

Метод сборки данных из доступных объектов системы. Метод имеет следующие объекты:

  • text_preprocessing_result — объект класса TextPreprocessingResult, который получается на основе поля payload.message из входящего сообщения;
  • filter_params — параметры, которые будут удалены при создании словаря.
def _get_user_data(self, text_preprocessing_result=None)

Метод, в котором задается набор данных, возвращаемый из метода collect. Метод имеет следующий объект:

  • text_preprocessing_result — объект класса TextPreprocessingResult, который получается на основе поля payload.message из входящего сообщения.
@lazy
def filter(self)

Свойство, которое возвращает объект класса Filter.

def filter_out(self, data, filter_params=None)

Метод, который отфильтровывает данные из созданного словаря в методе _get_user_data. Метод имеет следующие объекты:

  • data — словарь, созданный в методе _get_user_data;
  • filter_params — параметры, которые нужно удалить из словаря.

В большинстве случаев при создании смартапа достаточно переопределить в классе наследника метод _get_user_data, в котором можно обогатить новыми данными текущий словарь с параметрами.

LoggerMessageCreator — расширение параметров логирования

LoggerMessageCreator — класс, который используется для ведения логов смартапа. Переопределив методы класса можно указать какие параметры будут отображаться в логах.

Создав наследника от класса, можно переопределить следующие методы:

def update_user_params(cls, user, params)

Метод вызывается в make_message до маскирования и добавляет в сообщение лога параметры заданные в массиве ART_NAME. Переопределите метод, чтобы изменить список параметров.

  • user — объект класса User или производный от этого класса;
def update_other_params(cls, user, params, cls_name='', log_store_for=0)

Метод вызывается в make_message после маскирования и добавляет в сообщение лога дополнительные параметры. Переопределите метод, чтобы изменить или дополнить параметры сообщения лога.

  • user — объект класса User или производный от этого класса;
def make_message(cls, user=None, params=None, cls_name='', log_store_for=0)

Метод возвращает параметры, которые передаются в сообщении лога смартапа. Часть параметров маскируется, например, персональные данные пользователей.

  • user — объект класса User или производный от этого класса;

Settings — загрузка конфигов

Settings — класс, который загружает конфиги смартапа. Например: template_config.yml, kafka_config.yml, ceph_config.yml. Создав наследника от класса, можно переопределить следующие методы:

def override_repositories(self, repositories: list)

Метод предназначен для добавления новых репозиториев в дочерних классах. Метод принимает объект repositories — список репозиториев класса SmartAppResources. На выходе ожидается дополненный список repositories новыми сущностями, характерными для конкретного смартапа.

def get_source(self)

Метод определяет, каким адаптером будут загружены конфиги:

  • OSAdapter — используется по умолчанию. Адаптер ищет файлы локально.
  • CephAdapter — позволяет загружать файлы из s3 хранилища

Как результат работы ожидается объект наследник от класса DBAdapter.

Как подключить свои классы

После создания собственных классов необходимо добавить их в смартап. Для этого необходимо:

  1. Зарегистрировать собственные классы в app_config.py.
  2. C помощью конструкции from ... import подключить класс.
  3. Присвоить переменной соответствующий ей класс: LOCAL_TESTING — наследник от класса CLInterface; RESOURCES — наследник от класса SmartAppResources; USER — наследник от класса BaseUser; MAIN_LOOP — наследник от класса MainLoop; PARAMETRIZER — наследник от класса BasicParametrizer; MODEL — наследник от класса SmartAppModel; DIALOG_MANAGER — наследник от класса DialogManager; SETTINGS — наследник от класса Settings.

Например:

from app.local_testing.custom_local_testing import CustomLocalTesting
from app.resources.custom_app_resourses import CustomAppResourses

LOCAL_TESTING = CustomLocalTesting
RESOURCES = CustomAppResourses

Заметили ошибку?

Выделите текст и нажмите Ctrl + Enter, чтобы сообщить нам о ней