-
Notifications
You must be signed in to change notification settings - Fork 0
CreatingBackend RU
Актуально с версии 1.0.0
💅 В этой статье будет описан алгоритм реализации своего бекенда для Mess на примере реализации "MyLangBackend" - бекенда для "MyLang"
---
title: Связи между компонентами бекенда
---
graph TD;
backend.py:MyLangBackend-- Создание сообщения ---> mylang.py{{Сообщение реализовано в messages/mylang.py}}
backend.py:MyLangBackend-- Рендеринг сообщения ---> mylang.py
mylang.py --> |Да| messages/mylang.py
mylang.py --> |Нет| messages/base.py
messages/base.py-- Рендеринг сообщения --> d(NotImplementedException)
messages/mylang.py-- Манглинг-->backend.py:MyLangBackend;
messages/mylang.py-- Рендеринг сообщения -->templates/mylang/*.j2;
templates/mylang/*.j2-- Получение информации о сообщении -->messages/mylang.py;
Наш класс бекенда, унаследоваемый от Backend, необходимо обьявить в backend.py, ниже всех обьявленных до него. Это необходимо для правильной работы автоматического поиска реализованных бекендов.
💁 На данный момент (версия 1.0.0), поиск бекендов происходит в
mess.py
, в последующих версиях это будет изменено и вынесено в отдельный файл
Итак, добавим этот код в конец файла backend.py:
class MyLangBackend(Backend):
# Код бекенда
name = "mylang"
# Название директории с шаблонами
path_to_templates = "mylang/"
def render_message(self, message: messages_base.Message):
return super().render_message(message)
Здесь, мы создаем класс MyLangBackend, наследуемый от Backend, и определяем значения его default values полей.
Поле name
определяет адресуемое имя бекенда, которое используется при выборе бекендов, когда пользователь запускает скрипт генерации mess.py <name> <out> <in>
Поле path_to_templates
указывает на местоположение файлов шаблонов бекенда. Этот путь складывается таким образом - /templates/<path_to_templates>
, то есть в данном случае: /templates/mylang/
💁 В данном примере специально оставлен метод
MyLangBackend::render_message
, хотя в данном случае его можно упустить. Сделано это было для того, чтобы показать, что здесь есть возможность переопределить дальнейший алгоритм, вместо стандартного (см. граф выше).
🙌 Полное описание базового класса Backend можно посмотреть тут, либо в файле
Backend.py
Бекенд создает экземпляры необходимых сообщений, встроенных, затем пользовательских (с ini файла). Для создания он использует, либо реализацию сообщения из messages/base.py
, либо, если такое есть, из messages/mylang.py
.
💁 Сделано это было для того, чтобы при добавлении в
base.py
нового сообщения, пока нет реализации этого сообщения у текущего бекенда, и оно используется в описании у пользователя , происходил выброс исключенияNotImplementedException
, которое позволяет сразу выявить такое сообщение.
В директории /messages/
необходимо создать mylang.py
, в котором реализовать все сообщения из base.py
, главное здесь - переопределить метод base.Message::render
и base.Message::get_render_template
, именно в них происходит выброс исключения.
🙌 Посмотреть список всех встроенных сообщений, зарегистрированных в Mess, можно тут или в файле
messages/base.py
Приведем здесь пример одного такого сообщения (взято из imhex.py
):
class Message(base.Message):
def __init__(self, name=None, fields=None, generic_args=None, docs=None):
super().__init__(name, fields, generic_args, docs)
def render(self, backend: 'Backend'):
return backend.get_template(self.get_render_template()) \
.render(data={'message': self, 'backend': backend})
def get_render_template(self) -> str:
return "Type.j2"
Здесь переопределяется метод mylang.Message::get_render_template
, в котором происходит только возвращение имени шаблона, а также метод mylang.Message::render
.
В методе mylang.Message::render
получает шаблон и рендерит его, передавая data
.
💁 Для реализации своего бекенда лучше скопировать
base.py
и реализовывать сообщения там, или жеcpp.py
, где уже есть работа с шаблоном.
Здесь есть большой потенциал к изменению входных параметров, это все зависит от того, что принимает шаблон.
💁 Здесь начинается самое интересное! Именно тут и определяется как будет выглядеть результат рендеринга.
В директории /templates/mylang/
создаем файл Type.j2
с таким содержанием (взято из templates/imhex/Type.j2
):
{% set msg = message %}
{# First simple fields (non variative), then complex, variative #}
{% set sorted_fields = msg.fields | sort(attribute="message.is_variative") %}
struct {{ msg | message_type }} {
{% for field in sorted_fields %}
{{ field | field_type }} {{ field | field_name }};
{% endfor %}
};
🙌 Шаблон сильно упрощен, для лучшего понимания (например, здесь не хватает поддержки коментариев, хеширования протокола). Полные, реальные, примеры можно посмотреть в
/templates/
.
Данный шаблон реализует структуру с замангленным именем сообщения, используя фильтр message_type
, и полями этого сообщения.
🙌 Посмотреть полный список фильтров можно тут или же в файле
filters.py
.
--
В конечном счете, надеюсь мне удалось хотя бы примерно обьяснить как происходит реализация своего бекенда. Эта статья и все остальные будут постепенно дополняться, чтобы сделать Mess более понятным для всех 🙆♀️
🙋 Если у вас есть вопросы, можно их задавать в Discussions или Issues репозитория Mess на Github. Также предложения и PR приветствуются!
Вернуться к: Главная | Реализация своего бекенда