feat: pydantic descriptors

This commit is contained in:
TheNoxium
2025-10-06 19:13:55 +05:00
parent 8e01072ff6
commit 46d9381905
28 changed files with 589 additions and 582 deletions

View File

@@ -1,7 +1,7 @@
from .vork_node import VorkNode from .vork_node import VorkNode
from .vork_node_registry import VorkNodeRegistry from .vork_node_registry import VorkNodeRegistry
from .vork_node_link import VorkNodeLink from .vork_node_link import VorkNodeLink
from .vork_node_start import VorkNodeStart from .vork_node_test import VorkNodeTest
from .link_name_generator import edge_title_generator, edge_title_to_number from .link_name_generator import edge_title_generator, edge_title_to_number
__version__ = "0.1.0" __version__ = "0.1.0"
@@ -11,7 +11,7 @@ __all__ = [
"VorkNode", "VorkNode",
"VorkNodeRegistry", "VorkNodeRegistry",
"VorkNodeLink", "VorkNodeLink",
"VorkNodeStart", "VorkNodeTest",
"edge_title_generator", "edge_title_generator",
"edge_title_to_number", "edge_title_to_number",
] ]

View File

@@ -1,460 +0,0 @@
from typing import Dict, Any
# Дескриптор формы для узла IF
IF_FORM_DESCRIPTOR = {
"elements": [
{
"name": "condition_row",
"type": "row",
"label": "Условие проверки",
"link_port": {
"id": "then_output",
"label": "Then"
},
"elements": [
{
"name": "condition",
"type": "area",
"label": "Условие",
"placeholder": "Введите условие"
}
]
},
{
"name": "else_row",
"type": "row",
"label": "Альтернативный путь",
"link_port": {
"id": "else_output",
"label": "Else"
}
}
]
}
# Дескриптор формы для узла Listen
LISTEN_FORM_DESCRIPTOR = {
"elements": [
{
"name": "event_row",
"type": "row",
"label": "Событие",
"elements": [
{
"name": "event_name",
"type": "line",
"label": "Событие",
"placeholder": "Идентификатор события"
}
]
},
{
"name": "condition_row",
"type": "row",
"label": "Условие",
"elements": [
{
"name": "condition",
"type": "area",
"label": "Условие",
"placeholder": "Если P([condition(i), [AND, OR]]) == true"
}
]
},
{
"name": "then_row",
"type": "row",
"label": "Then",
"link_port": {
"id": "then_output",
"label": "Then"
}
}
]
}
# Дескриптор формы для узла Trigger
TRIGGER_FORM_DESCRIPTOR = {
"elements": [
{
"name": "event_row",
"type": "row",
"label": "Событие",
"elements": [
{
"name": "event_name",
"type": "line",
"label": "Событие",
"placeholder": "Идентификатор события"
}
]
},
{
"name": "context_row",
"type": "row",
"label": "Контекст",
"elements": [
{
"name": "context",
"type": "area",
"label": "Данные",
"placeholder": "Подготовка указанных переменных окружения в формат запроса JSON"
}
]
},
{
"name": "then_row",
"type": "row",
"label": "Then",
"link_port": {
"id": "then_output",
"label": "Then"
}
}
]
}
# Дескриптор формы для узла Run
RUN_FORM_DESCRIPTOR = {
"elements": [
{
"name": "task_row",
"type": "row",
"label": "Задача",
"elements": [
{
"name": "task",
"type": "select",
"label": "Задача",
"data": ["send_email", "process_data", "generate_report", "validate_input", "transform_data"],
"default": "send_email"
}
]
},
{
"name": "context_row",
"type": "row",
"label": "Аргументы",
"elements": [
{
"name": "context",
"type": "area",
"label": "Аргументы",
"placeholder": "Подготовка указанных переменных окружения в формат запроса JSON"
}
]
},
{
"name": "then_row",
"type": "row",
"label": "Then",
"link_port": {
"id": "then_output",
"label": "Then"
}
}
]
}
# Дескриптор формы для узла Callback
CALLBACK_FORM_DESCRIPTOR = {
"elements": [
{
"name": "uri_row",
"type": "row",
"label": "URI",
"elements": [
{
"name": "uri",
"type": "line",
"label": "Событие",
"placeholder": "URI хука"
}
]
},
{
"name": "method_row",
"type": "row",
"label": "Метод",
"elements": [
{
"name": "method",
"type": "select",
"label": "Метод",
"data": ["POST", "GET", "PUT", "PATCH", "DELETE"],
"default": "POST"
}
]
},
{
"name": "headers_row",
"type": "row",
"label": "Заголовки",
"elements": [
{
"name": "headers",
"type": "area",
"label": "Заголовки",
"placeholder": "Приведение и валидация заголовков"
}
]
},
{
"name": "body_row",
"type": "row",
"label": "Данные",
"elements": [
{
"name": "body",
"type": "area",
"label": "Данные",
"placeholder": "Приведение значений и валидация JSON"
}
]
},
{
"name": "sync_row",
"type": "row",
"label": "Ожидать выполнение запроса",
"elements": [
{
"name": "sync",
"type": "select",
"label": "Ожидать выполнение запроса",
"data": ["Да", "Нет"],
"default": "Да"
}
]
},
{
"name": "then_row",
"type": "row",
"label": "Then",
"link_port": {
"id": "then_output",
"label": "Then"
}
}
]
}
# Дескриптор формы для узла Switch
SWITCH_FORM_DESCRIPTOR = {
"elements": [
{
"name": "switch_row",
"type": "row",
"label": "Условие проверки",
"link_port": {
"id": "case_1_output",
"label": "case_1",
"is_addable": True
},
"elements": [
{
"name": "switch_value",
"type": "area",
"label": "Условие проверки",
"placeholder": "Введите условие"
}
]
},
{
"name": "default_row",
"type": "row",
"label": "По умолчанию",
"link_port": {
"id": "default_output",
"label": "default"
}
}
]
}
# Дескриптор формы для узла Set
SET_FORM_DESCRIPTOR = {
"elements": [
{
"name": "variable_row",
"type": "row",
"label": "Имя параметра",
"elements": [
{
"name": "variable",
"type": "line",
"label": "Имя параметра",
"placeholder": "Введите имя параметра"
}
]
},
{
"name": "value_row",
"type": "row",
"label": "Параметр",
"elements": [
{
"name": "value",
"type": "area",
"label": "Параметр",
"placeholder": "Введите значение"
}
]
},
{
"name": "link_row",
"type": "row",
"label": "Связь",
"link_port": {
"id": "then_output",
"label": "then"
},
"elements": []
}
]
}
# Дескриптор формы для узла Wait
WAIT_FORM_DESCRIPTOR = {
"elements": [
{
"name": "type_row",
"type": "row",
"label": "Параметр",
"elements": [
{
"name": "type",
"type": "select",
"label": "Параметр",
"data": ["seconds", "datetime"],
"placeholder": "Выбранный вариант"
}
]
},
{
"name": "wait_for_row",
"type": "row",
"label": "Время",
"elements": [
{
"name": "wait_for",
"type": "number",
"label": "Время",
"placeholder": "Вычислить значение ожидания в секундах"
}
]
},
{
"name": "wait_datetime_row",
"type": "row",
"label": "Подождать",
"elements": [
{
"name": "wait_datetime",
"type": "date",
"label": "Подождать",
"placeholder": "Вычислить значение до определённого времени"
}
]
},
{
"name": "then_row",
"type": "row",
"label": "Переход",
"link_port": {
"id": "then_output",
"label": "then"
}
}
]
}
# Дескриптор формы для узла While
WHILE_FORM_DESCRIPTOR = {
"elements": [
{
"name": "condition_row",
"type": "row",
"label": "Параметр",
"link_port": {
"id": "then_output",
"label": "Then"
},
"elements": [
{
"name": "condition",
"type": "area",
"label": "Параметр",
"placeholder": "P(condition) == true"
}
]
},
{
"name": "else_row",
"type": "row",
"label": "Альтернативный путь",
"link_port": {
"id": "else_output",
"label": "Else"
}
}
]
}
# Дескриптор формы для узла Each
EACH_FORM_DESCRIPTOR = {
"elements": [
{
"name": "list_row",
"type": "row",
"label": "Список",
"link_port": {
"id": "then_output",
"label": "Then"
},
"elements": [
{
"name": "list",
"type": "line",
"label": "Список",
"placeholder": "Валидация списка и получение очередного value из списка"
}
]
},
{
"name": "else_row",
"type": "row",
"label": "Альтернативный путь",
"link_port": {
"id": "else_output",
"label": "Else"
}
}
]
}
# Маппинг типов узлов на дескрипторы форм
FORM_DESCRIPTORS = {
"IF": IF_FORM_DESCRIPTOR,
"LISTEN": LISTEN_FORM_DESCRIPTOR,
"TRIGGER": TRIGGER_FORM_DESCRIPTOR,
"RUN": RUN_FORM_DESCRIPTOR,
"CALLBACK": CALLBACK_FORM_DESCRIPTOR,
"SWITCH": SWITCH_FORM_DESCRIPTOR,
"SET": SET_FORM_DESCRIPTOR,
"WAIT": WAIT_FORM_DESCRIPTOR,
"WHILE": WHILE_FORM_DESCRIPTOR,
"EACH": EACH_FORM_DESCRIPTOR,
}
def get_form_descriptor(node_type: str) -> Dict[str, Any]:
"""
Получить дескриптор формы для указанного типа узла
Args:
node_type: Тип узла (например, "node_if")
Returns:
Dict с дескриптором формы или пустой dict если тип не найден
"""
return FORM_DESCRIPTORS.get(node_type, {})

View File

@@ -1,63 +0,0 @@
from typing import Dict, Any
from .vork_node import VorkNode
from model_nodes.node_start_models import (
StartNodeData,
StartNodeCoreSchema,
StartNodeCoreSchemaData
)
class VorkNodeStart(VorkNode):
def __init__(self, data: Dict[str, Any], links: Dict[str, Any] = None):
"""
Инициализация стартового узла
"""
super().__init__(data, links or {})
@property
def id(self) -> str:
return "START"
@classmethod
def form(cls) -> StartNodeCoreSchema:
"""
Возвращает схему узла start для UI
"""
return StartNodeCoreSchema()
def validate(self) -> StartNodeCoreSchema:
"""
Валидирует данные узла start и возвращает схему
"""
try:
# Валидируем данные узла
validated_data = self.validate_data()
node_data = StartNodeCoreSchemaData(
node_port_number=0,
)
# Создаем схему с валидированными данными
return StartNodeCoreSchema(
ps_id=validated_data.ps_id,
node_type=validated_data.node_type,
data=node_data
)
except Exception as e:
print(f"Start node validation error: {e}")
raise
def validate_data(self) -> StartNodeData:
"""
Валидирует данные узла start
"""
return StartNodeData(**self.data)
def process(self, context):
"""
Обрабатывает узел start - точка входа в процесс
"""
# Start узел просто передает управление дальше
# Здесь может быть логика инициализации процесса
pass

49
core/vork_node_test.py Normal file
View File

@@ -0,0 +1,49 @@
from typing import Dict, Any
from .vork_node import VorkNode
from model_nodes.node_test_models import (
TestNodeData,
TestNodeCoreSchema,
TestNodeCoreSchemaData
)
class VorkNodeTest(VorkNode):
def __init__(self, data: Dict[str, Any], links: Dict[str, Any] = None):
"""
Инициализация узла test
"""
super().__init__(data, links or {})
@property
def id(self) -> str:
return "TEST"
@classmethod
def form(cls) -> TestNodeCoreSchema:
"""
Возвращает схему узла test для UI
"""
return TestNodeCoreSchema()
def validate(self) -> TestNodeCoreSchema:
"""
Валидирует данные узла test и возвращает схему
"""
try:
validated_data = self.validate_data()
node_data = TestNodeCoreSchemaData(node_port_number=0)
return TestNodeCoreSchema(
ps_id=validated_data.ps_id,
node_type=validated_data.node_type,
data=node_data
)
except Exception as e:
print(f"Test node validation error: {e}")
raise
def validate_data(self) -> TestNodeData:
return TestNodeData(**self.data)
def process(self, context):
pass

View File

@@ -38,12 +38,12 @@ from .node_if_models import (
IfNodeCoreSchemaData IfNodeCoreSchemaData
) )
# Экспорты для моделей узла start # Экспорты для моделей узла test (ранее start)
from .node_start_models import ( from .node_test_models import (
StartNodeData, TestNodeData,
StartNodeLinks, TestNodeLinks,
StartNodeCoreSchema, TestNodeCoreSchema,
StartNodeCoreSchemaData TestNodeCoreSchemaData
) )
# Экспорты для моделей узла switch # Экспорты для моделей узла switch
@@ -123,11 +123,11 @@ __all__ = [
"IfNodeCoreSchema", "IfNodeCoreSchema",
"IfNodeCoreSchemaData", "IfNodeCoreSchemaData",
# Start node models # Test node models
"StartNodeData", "TestNodeData",
"StartNodeLinks", "TestNodeLinks",
"StartNodeCoreSchema", "TestNodeCoreSchema",
"StartNodeCoreSchemaData", "TestNodeCoreSchemaData",
# Switch node models # Switch node models
"SwitchNodeData", "SwitchNodeData",

View File

@@ -0,0 +1,75 @@
from __future__ import annotations
from typing import Optional, Annotated, Literal, List
from pydantic import BaseModel, Field
class LinkPort(BaseModel):
id: str
label: str
is_addable: Optional[bool] = None
class LineElement(BaseModel):
type: Literal['line']
name: str
label: str
placeholder: Optional[str] = None
class AreaElement(BaseModel):
type: Literal['area']
name: str
label: str
placeholder: Optional[str] = None
class SelectElement(BaseModel):
type: Literal['select']
name: str
label: str
data: List[str]
default: Optional[str] = None
placeholder: Optional[str] = None
class NumberElement(BaseModel):
type: Literal['number']
name: str
label: str
placeholder: Optional[str] = None
class DateElement(BaseModel):
type: Literal['date']
name: str
label: str
placeholder: Optional[str] = None
FieldElement = Annotated[
LineElement | AreaElement | SelectElement | NumberElement | DateElement,
Field(discriminator='type'),
]
class RowElement(BaseModel):
type: Literal['row']
name: str
label: str
link_port: Optional[LinkPort] = None
elements: Optional[List[FieldElement]] = None
class FormDescriptor(BaseModel):
elements: List[RowElement]
# Descriptor-suffixed aliases for clarity (backward compatible)
LinkPortDescriptor = LinkPort
LineElementDescriptor = LineElement
AreaElementDescriptor = AreaElement
SelectElementDescriptor = SelectElement
NumberElementDescriptor = NumberElement
DateElementDescriptor = DateElement
RowDescriptor = RowElement
FormDescriptorModel = FormDescriptor

View File

@@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .form_base_descriptor_models import FormDescriptor, RowElement, LineElement, AreaElement, SelectElement, LinkPort
class CallbackNodeData(BaseModel): class CallbackNodeData(BaseModel):
@@ -34,3 +35,83 @@ class CallbackNodeCoreSchema(BaseModel):
parent_id: Optional[int] = Field(default=None, description="ID родительского узла") parent_id: Optional[int] = Field(default=None, description="ID родительского узла")
parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла") parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла")
data: Optional[CallbackNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[CallbackNodeCoreSchemaData] = Field(default=None, description="Данные узла")
# Дескриптор формы узла CALLBACK
CALLBACK_FORM_DESCRIPTOR = FormDescriptor(
elements=[
RowElement(
name="uri_row",
type="row",
label="URI",
elements=[
LineElement(
name="uri",
type="line",
label="URI",
placeholder="Webhook URL",
)
],
),
RowElement(
name="method_row",
type="row",
label="Method",
elements=[
SelectElement(
name="method",
type="select",
label="Method",
data=["POST", "GET", "PUT", "PATCH", "DELETE"],
default="POST",
)
],
),
RowElement(
name="headers_row",
type="row",
label="Headers",
elements=[
AreaElement(
name="headers",
type="area",
label="Headers",
placeholder="Normalize and validate headers",
)
],
),
RowElement(
name="body_row",
type="row",
label="Body",
elements=[
AreaElement(
name="body",
type="area",
label="Data",
placeholder="Normalize values and validate JSON",
)
],
),
RowElement(
name="sync_row",
type="row",
label="Wait for request completion",
elements=[
SelectElement(
name="sync",
type="select",
label="Wait for request completion",
data=["Yes", "No"],
default="Yes",
)
],
),
RowElement(
name="then_row",
type="row",
label="Then",
link_port=LinkPort(id="then_output", label="Then"),
),
]
)

View File

@@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .form_base_descriptor_models import FormDescriptor, RowElement, LineElement, LinkPort
class EachNodeData(BaseModel): class EachNodeData(BaseModel):
@@ -35,3 +36,30 @@ class EachNodeCoreSchema(BaseModel):
parent_id: Optional[int] = Field(default=None, description="ID родительского узла") parent_id: Optional[int] = Field(default=None, description="ID родительского узла")
parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла") parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла")
data: Optional[EachNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[EachNodeCoreSchemaData] = Field(default=None, description="Данные узла")
# Дескриптор формы узла EACH
EACH_FORM_DESCRIPTOR = FormDescriptor(
elements=[
RowElement(
name="list_row",
type="row",
label="List",
link_port=LinkPort(id="then_output", label="Then"),
elements=[
LineElement(
name="list",
type="line",
label="List",
placeholder="Validate list and extract next value from list",
)
],
),
RowElement(
name="else_row",
type="row",
label="Alternative path",
link_port=LinkPort(id="else_output", label="Else"),
),
]
)

View File

@@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .form_base_descriptor_models import FormDescriptor, RowElement, AreaElement, LinkPort
class IfNodeData(BaseModel): class IfNodeData(BaseModel):
@@ -35,3 +36,30 @@ class IfNodeCoreSchema(BaseModel):
parent_id: Optional[int] = Field(default=None, description="ID родительского узла") parent_id: Optional[int] = Field(default=None, description="ID родительского узла")
parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла") parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла")
data: Optional[IfNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[IfNodeCoreSchemaData] = Field(default=None, description="Данные узла")
# Дескриптор формы узла IF
IF_FORM_DESCRIPTOR = FormDescriptor(
elements=[
RowElement(
name="condition_row",
type="row",
label="Condition",
link_port=LinkPort(id="then_output", label="Then"),
elements=[
AreaElement(
name="condition",
type="area",
label="Condition",
placeholder="Enter condition",
)
],
),
RowElement(
name="else_row",
type="row",
label="Alternative path",
link_port=LinkPort(id="else_output", label="Else"),
),
]
)

View File

@@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .form_base_descriptor_models import FormDescriptor, RowElement, LineElement, AreaElement, LinkPort
class ListenNodeData(BaseModel): class ListenNodeData(BaseModel):
@@ -36,3 +37,42 @@ class ListenNodeCoreSchema(BaseModel):
parent_id: Optional[int] = Field(default=None, description="ID родительского узла") parent_id: Optional[int] = Field(default=None, description="ID родительского узла")
parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла") parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла")
data: Optional[ListenNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[ListenNodeCoreSchemaData] = Field(default=None, description="Данные узла")
# Дескриптор формы узла LISTEN
LISTEN_FORM_DESCRIPTOR = FormDescriptor(
elements=[
RowElement(
name="event_row",
type="row",
label="Event",
elements=[
LineElement(
name="event_name",
type="line",
label="Event",
placeholder="Event identifier",
)
],
),
RowElement(
name="condition_row",
type="row",
label="Condition",
elements=[
AreaElement(
name="condition",
type="area",
label="Condition",
placeholder="If P([condition(i), [AND, OR]]) == true",
)
],
),
RowElement(
name="then_row",
type="row",
label="Then",
link_port=LinkPort(id="then_output", label="Then"),
),
]
)

View File

@@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .form_base_descriptor_models import FormDescriptor, RowElement, AreaElement, SelectElement, LinkPort
class RunNodeData(BaseModel): class RunNodeData(BaseModel):
@@ -34,3 +35,43 @@ class RunNodeCoreSchema(BaseModel):
parent_id: Optional[int] = Field(default=None, description="ID родительского узла") parent_id: Optional[int] = Field(default=None, description="ID родительского узла")
parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла") parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла")
data: Optional[RunNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[RunNodeCoreSchemaData] = Field(default=None, description="Данные узла")
# Дескриптор формы для узла Run
RUN_FORM_DESCRIPTOR = FormDescriptor(
elements=[
RowElement(
name="task_row",
type="row",
label="Task",
elements=[
SelectElement(
name="task",
type="select",
label="Task",
data=["send_email", "process_data", "generate_report", "validate_input", "transform_data"],
default="send_email",
)
],
),
RowElement(
name="context_row",
type="row",
label="Arguments",
elements=[
AreaElement(
name="context",
type="area",
label="Arguments",
placeholder="Build request JSON from provided environment variables",
)
],
),
RowElement(
name="then_row",
type="row",
label="Then",
link_port=LinkPort(id="then_output", label="Then"),
),
]
)

View File

@@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .form_base_descriptor_models import FormDescriptor, RowElement, LineElement, AreaElement, LinkPort
class SetNodeData(BaseModel): class SetNodeData(BaseModel):
@@ -34,3 +35,43 @@ class SetNodeCoreSchema(BaseModel):
parent_id: Optional[int] = Field(default=None, description="ID родительского узла") parent_id: Optional[int] = Field(default=None, description="ID родительского узла")
parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла") parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла")
data: Optional[SetNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[SetNodeCoreSchemaData] = Field(default=None, description="Данные узла")
# Дескриптор формы узла SET
SET_FORM_DESCRIPTOR = FormDescriptor(
elements=[
RowElement(
name="variable_row",
type="row",
label="Parameter name",
elements=[
LineElement(
name="variable",
type="line",
label="Parameter name",
placeholder="Enter parameter name",
)
],
),
RowElement(
name="value_row",
type="row",
label="Value",
elements=[
AreaElement(
name="value",
type="area",
label="Value",
placeholder="Enter value",
)
],
),
RowElement(
name="link_row",
type="row",
label="Link",
link_port=LinkPort(id="then_output", label="then"),
elements=[],
),
]
)

View File

@@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .form_base_descriptor_models import FormDescriptor, RowElement, AreaElement, LinkPort
class SwitchNodeData(BaseModel): class SwitchNodeData(BaseModel):
@@ -35,3 +36,30 @@ class SwitchNodeCoreSchema(BaseModel):
parent_id: Optional[int] = Field(default=None, description="ID родительского узла") parent_id: Optional[int] = Field(default=None, description="ID родительского узла")
parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла") parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла")
data: Optional[SwitchNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[SwitchNodeCoreSchemaData] = Field(default=None, description="Данные узла")
# Дескриптор формы узла SWITCH
SWITCH_FORM_DESCRIPTOR = FormDescriptor(
elements=[
RowElement(
name="switch_row",
type="row",
label="Switch condition",
link_port=LinkPort(id="case_1_output", label="case_1", is_addable=True),
elements=[
AreaElement(
name="switch_value",
type="area",
label="Switch condition",
placeholder="Enter condition",
)
],
),
RowElement(
name="default_row",
type="row",
label="Default",
link_port=LinkPort(id="default_output", label="default"),
),
]
)

View File

@@ -1,33 +1,33 @@
from typing import Optional, Dict, Any from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
class StartNodeData(BaseModel): class TestNodeData(BaseModel):
""" """
Pydantic модель для валидации данных узла start Pydantic модель для валидации данных узла test
""" """
ps_id: Optional[int] = Field(default=None, description="ID процесса") ps_id: Optional[int] = Field(default=None, description="ID процесса")
node_type: Optional[str] = Field(default=None, description="Тип узла") node_type: Optional[str] = Field(default=None, description="Тип узла")
class StartNodeLinks(BaseModel): class TestNodeLinks(BaseModel):
""" """
Pydantic модель для валидации связей узла start Pydantic модель для валидации связей узла test
""" """
# Start узел не имеет родительских связей, только исходящие # Test узел не имеет родительских связей, только исходящие
class StartNodeCoreSchemaData(BaseModel): class TestNodeCoreSchemaData(BaseModel):
""" """
Pydantic модель для данных портов узла start Pydantic модель для данных портов узла test
""" """
node_port_number: Optional[int] = Field(default=0, description="Номер порта для перехода по Связи Then (LINK)") node_port_number: Optional[int] = Field(default=0, description="Номер порта для перехода по Связи Then (LINK)")
class StartNodeCoreSchema(BaseModel): class TestNodeCoreSchema(BaseModel):
""" """
Pydantic модель для схемы узла start Pydantic модель для схемы узла test
""" """
ps_id: Optional[int] = Field(default=None, description="ID процесса") ps_id: Optional[int] = Field(default=None, description="ID процесса")
node_type: Optional[str] = Field(default=None, description="Тип узла") node_type: Optional[str] = Field(default=None, description="Тип узла")
data: Optional[StartNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[TestNodeCoreSchemaData] = Field(default=None, description="Данные узла")

View File

@@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .form_base_descriptor_models import FormDescriptor, RowElement, LineElement, AreaElement, LinkPort
class TriggerNodeData(BaseModel): class TriggerNodeData(BaseModel):
@@ -34,3 +35,42 @@ class TriggerNodeCoreSchema(BaseModel):
parent_id: Optional[int] = Field(default=None, description="ID родительского узла") parent_id: Optional[int] = Field(default=None, description="ID родительского узла")
parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла") parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла")
data: Optional[TriggerNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[TriggerNodeCoreSchemaData] = Field(default=None, description="Данные узла")
# Дескриптор формы узла TRIGGER
TRIGGER_FORM_DESCRIPTOR = FormDescriptor(
elements=[
RowElement(
name="event_row",
type="row",
label="Event",
elements=[
LineElement(
name="event_name",
type="line",
label="Event",
placeholder="Event identifier",
)
],
),
RowElement(
name="context_row",
type="row",
label="Context",
elements=[
AreaElement(
name="context",
type="area",
label="Payload",
placeholder="Build request JSON from provided environment variables",
)
],
),
RowElement(
name="then_row",
type="row",
label="Then",
link_port=LinkPort(id="then_output", label="Then"),
),
]
)

View File

@@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .form_base_descriptor_models import FormDescriptor, RowElement, SelectElement, NumberElement, DateElement, LinkPort
class WaitNodeData(BaseModel): class WaitNodeData(BaseModel):
@@ -34,3 +35,56 @@ class WaitNodeCoreSchema(BaseModel):
parent_id: Optional[int] = Field(default=None, description="ID родительского узла") parent_id: Optional[int] = Field(default=None, description="ID родительского узла")
parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла") parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла")
data: Optional[WaitNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[WaitNodeCoreSchemaData] = Field(default=None, description="Данные узла")
# Дескриптор формы узла WAIT
WAIT_FORM_DESCRIPTOR = FormDescriptor(
elements=[
RowElement(
name="type_row",
type="row",
label="Parameter",
elements=[
SelectElement(
name="type",
type="select",
label="Parameter",
data=["seconds", "datetime"],
placeholder="Selected option",
)
],
),
RowElement(
name="wait_for_row",
type="row",
label="Time",
elements=[
NumberElement(
name="wait_for",
type="number",
label="Time",
placeholder="Compute wait time in seconds",
)
],
),
RowElement(
name="wait_datetime_row",
type="row",
label="Wait until",
elements=[
DateElement(
name="wait_datetime",
type="date",
label="Wait until",
placeholder="Compute value until specific datetime",
)
],
),
RowElement(
name="then_row",
type="row",
label="Transition",
link_port=LinkPort(id="then_output", label="then"),
),
]
)

View File

@@ -1,5 +1,6 @@
from typing import Optional from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from .form_base_descriptor_models import FormDescriptor, RowElement, AreaElement, LinkPort
class WhileNodeData(BaseModel): class WhileNodeData(BaseModel):
@@ -35,3 +36,30 @@ class WhileNodeCoreSchema(BaseModel):
parent_id: Optional[int] = Field(default=None, description="ID родительского узла") parent_id: Optional[int] = Field(default=None, description="ID родительского узла")
parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла") parent_port_number: Optional[int] = Field(default=None, description="Номер порта родительского узла")
data: Optional[WhileNodeCoreSchemaData] = Field(default=None, description="Данные узла") data: Optional[WhileNodeCoreSchemaData] = Field(default=None, description="Данные узла")
# Дескриптор формы узла WHILE
WHILE_FORM_DESCRIPTOR = FormDescriptor(
elements=[
RowElement(
name="condition_row",
type="row",
label="Parameter",
link_port=LinkPort(id="then_output", label="Then"),
elements=[
AreaElement(
name="condition",
type="area",
label="Parameter",
placeholder="P(condition) == true",
)
],
),
RowElement(
name="else_row",
type="row",
label="Alternative path",
link_port=LinkPort(id="else_output", label="Else"),
),
]
)

View File

@@ -1,13 +1,11 @@
from typing import Dict, Any from typing import Dict, Any
import requests
import json
from core import VorkNode from core import VorkNode
from core.form_descriptors import get_form_descriptor
from model_nodes.node_callback_models import ( from model_nodes.node_callback_models import (
CallbackNodeData, CallbackNodeData,
CallbackNodeLinks, CallbackNodeLinks,
CallbackNodeCoreSchema, CallbackNodeCoreSchema,
CallbackNodeCoreSchemaData CallbackNodeCoreSchemaData,
CALLBACK_FORM_DESCRIPTOR,
) )
@@ -28,7 +26,7 @@ class VorkNodeCallback(VorkNode):
""" """
Возвращает статический дескриптор формы для узла Callback Возвращает статический дескриптор формы для узла Callback
""" """
return get_form_descriptor("CALLBACK") return CALLBACK_FORM_DESCRIPTOR
def validate(self) -> CallbackNodeCoreSchema: def validate(self) -> CallbackNodeCoreSchema:
""" """

View File

@@ -1,11 +1,11 @@
from typing import Dict, Any from typing import Dict, Any
from core import VorkNode from core import VorkNode
from core.form_descriptors import get_form_descriptor
from model_nodes.node_each_models import ( from model_nodes.node_each_models import (
EachNodeData, EachNodeData,
EachNodeLinks, EachNodeLinks,
EachNodeCoreSchema, EachNodeCoreSchema,
EachNodeCoreSchemaData EachNodeCoreSchemaData,
EACH_FORM_DESCRIPTOR,
) )
@@ -26,7 +26,7 @@ class VorkNodeEach(VorkNode):
""" """
Возвращает статический дескриптор формы для узла Each Возвращает статический дескриптор формы для узла Each
""" """
return get_form_descriptor("EACH") return EACH_FORM_DESCRIPTOR
def validate(self) -> EachNodeCoreSchema: def validate(self) -> EachNodeCoreSchema:
""" """

View File

@@ -1,11 +1,11 @@
from typing import Any, Dict from typing import Any, Dict
from core import VorkNode from core import VorkNode
from core.form_descriptors import get_form_descriptor
from model_nodes.node_if_models import ( from model_nodes.node_if_models import (
IfNodeData, IfNodeData,
IfNodeLinks, IfNodeLinks,
IfNodeCoreSchema, IfNodeCoreSchema,
IfNodeCoreSchemaData IfNodeCoreSchemaData,
IF_FORM_DESCRIPTOR,
) )
@@ -20,7 +20,7 @@ class VorkNodeIf(VorkNode):
""" """
Возвращает статический дескриптор формы для узла IF Возвращает статический дескриптор формы для узла IF
""" """
return get_form_descriptor("IF") return IF_FORM_DESCRIPTOR
def validate(self) -> IfNodeCoreSchema: def validate(self) -> IfNodeCoreSchema:
""" """

View File

@@ -1,11 +1,11 @@
from typing import Dict, Any from typing import Dict, Any
from core import VorkNode from core import VorkNode
from core.form_descriptors import get_form_descriptor
from model_nodes.node_listen_models import ( from model_nodes.node_listen_models import (
ListenNodeData, ListenNodeData,
ListenNodeLinks, ListenNodeLinks,
ListenNodeCoreSchema, ListenNodeCoreSchema,
ListenNodeCoreSchemaData ListenNodeCoreSchemaData,
LISTEN_FORM_DESCRIPTOR,
) )
@@ -26,7 +26,7 @@ class VorkNodeListen(VorkNode):
""" """
Возвращает статический дескриптор формы для узла Listen Возвращает статический дескриптор формы для узла Listen
""" """
return get_form_descriptor("LISTEN") return LISTEN_FORM_DESCRIPTOR
def validate(self) -> ListenNodeCoreSchema: def validate(self) -> ListenNodeCoreSchema:
""" """

View File

@@ -1,12 +1,11 @@
from typing import Dict, Any from typing import Dict, Any
import json
from core import VorkNode from core import VorkNode
from core.form_descriptors import get_form_descriptor
from model_nodes.node_run_models import ( from model_nodes.node_run_models import (
RunNodeData, RunNodeData,
RunNodeLinks, RunNodeLinks,
RunNodeCoreSchema, RunNodeCoreSchema,
RunNodeCoreSchemaData RunNodeCoreSchemaData,
RUN_FORM_DESCRIPTOR,
) )
@@ -27,7 +26,7 @@ class VorkNodeRun(VorkNode):
""" """
Возвращает статический дескриптор формы для узла Run Возвращает статический дескриптор формы для узла Run
""" """
return get_form_descriptor("RUN") return RUN_FORM_DESCRIPTOR
def validate(self) -> RunNodeCoreSchema: def validate(self) -> RunNodeCoreSchema:
""" """

View File

@@ -1,11 +1,11 @@
from typing import Dict, Any from typing import Dict, Any
from core import VorkNode from core import VorkNode
from core.form_descriptors import get_form_descriptor
from model_nodes.node_set_models import ( from model_nodes.node_set_models import (
SetNodeData, SetNodeData,
SetNodeLinks, SetNodeLinks,
SetNodeCoreSchema, SetNodeCoreSchema,
SetNodeCoreSchemaData SetNodeCoreSchemaData,
SET_FORM_DESCRIPTOR,
) )
@@ -26,7 +26,7 @@ class VorkNodeSet(VorkNode):
""" """
Возвращает статический дескриптор формы для узла Set Возвращает статический дескриптор формы для узла Set
""" """
return get_form_descriptor("SET") return SET_FORM_DESCRIPTOR
def validate(self) -> SetNodeCoreSchema: def validate(self) -> SetNodeCoreSchema:
""" """

View File

@@ -1,11 +1,11 @@
from typing import Dict, Any from typing import Dict, Any
from core import VorkNode from core import VorkNode
from core.form_descriptors import get_form_descriptor
from model_nodes.node_switch_models import ( from model_nodes.node_switch_models import (
SwitchNodeData, SwitchNodeData,
SwitchNodeLinks, SwitchNodeLinks,
SwitchNodeCoreSchema, SwitchNodeCoreSchema,
SwitchNodeCoreSchemaData SwitchNodeCoreSchemaData,
SWITCH_FORM_DESCRIPTOR,
) )
@@ -26,7 +26,7 @@ class VorkNodeSwitch(VorkNode):
""" """
Возвращает статический дескриптор формы для узла Switch Возвращает статический дескриптор формы для узла Switch
""" """
return get_form_descriptor("SWITCH") return SWITCH_FORM_DESCRIPTOR
def validate(self) -> SwitchNodeCoreSchema: def validate(self) -> SwitchNodeCoreSchema:
""" """

View File

@@ -1,11 +1,11 @@
from typing import Dict, Any from typing import Dict, Any
from core import VorkNode from core import VorkNode
from core.form_descriptors import get_form_descriptor
from model_nodes.node_trigger_models import ( from model_nodes.node_trigger_models import (
TriggerNodeData, TriggerNodeData,
TriggerNodeLinks, TriggerNodeLinks,
TriggerNodeCoreSchema, TriggerNodeCoreSchema,
TriggerNodeCoreSchemaData TriggerNodeCoreSchemaData,
TRIGGER_FORM_DESCRIPTOR,
) )
@@ -26,7 +26,7 @@ class VorkNodeTrigger(VorkNode):
""" """
Возвращает статический дескриптор формы для узла Trigger Возвращает статический дескриптор формы для узла Trigger
""" """
return get_form_descriptor("TRIGGER") return TRIGGER_FORM_DESCRIPTOR
def validate(self) -> TriggerNodeCoreSchema: def validate(self) -> TriggerNodeCoreSchema:
""" """

View File

@@ -1,11 +1,11 @@
from typing import Dict, Any from typing import Dict, Any
from core import VorkNode from core import VorkNode
from core.form_descriptors import get_form_descriptor
from model_nodes.node_wait_models import ( from model_nodes.node_wait_models import (
WaitNodeData, WaitNodeData,
WaitNodeLinks, WaitNodeLinks,
WaitNodeCoreSchema, WaitNodeCoreSchema,
WaitNodeCoreSchemaData WaitNodeCoreSchemaData,
WAIT_FORM_DESCRIPTOR,
) )
@@ -26,7 +26,7 @@ class VorkNodeWait(VorkNode):
""" """
Возвращает статический дескриптор формы для узла Wait Возвращает статический дескриптор формы для узла Wait
""" """
return get_form_descriptor("WAIT") return WAIT_FORM_DESCRIPTOR
def validate(self) -> WaitNodeCoreSchema: def validate(self) -> WaitNodeCoreSchema:
""" """

View File

@@ -1,11 +1,11 @@
from typing import Dict, Any from typing import Dict, Any
from core import VorkNode from core import VorkNode
from core.form_descriptors import get_form_descriptor
from model_nodes.node_while_models import ( from model_nodes.node_while_models import (
WhileNodeData, WhileNodeData,
WhileNodeLinks, WhileNodeLinks,
WhileNodeCoreSchema, WhileNodeCoreSchema,
WhileNodeCoreSchemaData WhileNodeCoreSchemaData,
WHILE_FORM_DESCRIPTOR,
) )
@@ -26,7 +26,7 @@ class VorkNodeWhile(VorkNode):
""" """
Возвращает статический дескриптор формы для узла While Возвращает статический дескриптор формы для узла While
""" """
return get_form_descriptor("WHILE") return WHILE_FORM_DESCRIPTOR
def validate(self) -> WhileNodeCoreSchema: def validate(self) -> WhileNodeCoreSchema:
""" """

4
poetry.lock generated
View File

@@ -340,5 +340,5 @@ typing-extensions = ">=4.12.0"
[metadata] [metadata]
lock-version = "2.1" lock-version = "2.1"
python-versions = ">=3.9" python-versions = "^3.9"
content-hash = "903e152c7357bab4a5e2958b70731a876ff1280002b940bbf5d3d859ffa0d379" content-hash = "01d51b88c538d68359b01cf3a28e98633fafdf244e53550b790cb4ddd44eecac"