Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions backend/src/baserow/contrib/automation/nodes/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from django.core.files.storage import Storage
from django.db.models import QuerySet

from opentelemetry import trace

from baserow.contrib.automation.automation_dispatch_context import (
AutomationDispatchContext,
)
Expand All @@ -30,10 +32,13 @@
from baserow.core.services.handler import ServiceHandler
from baserow.core.services.models import Service
from baserow.core.storage import ExportZipFile
from baserow.core.telemetry.utils import baserow_trace_methods
from baserow.core.utils import ChildProgressBuilder, MirrorDict, extract_allowed

tracer = trace.get_tracer(__name__)


class AutomationNodeHandler:
class AutomationNodeHandler(metaclass=baserow_trace_methods(tracer)):
allowed_fields = [
"label",
"service",
Expand Down Expand Up @@ -107,11 +112,12 @@ def invalidate_node_cache(self, workflow):
local_cache.delete(self._get_node_cache_key(workflow, True))
local_cache.delete(self._get_node_cache_key(workflow, False))

def get_children(self, node, specific=True):
def get_children(self, node: AutomationNode) -> List[AutomationNode]:
"""
Returns the direct children of the given node.

:param specific: Whether to return specific node instances.
:param node: The parent node.
:return: A list of node instances that are the children of the given node.
"""

return node.workflow.get_graph().get_children(node)
Expand Down Expand Up @@ -250,7 +256,7 @@ def import_node(
) -> AutomationNode:
"""
Creates an instance of AutomationNode using the serialized version
previously exported with `.export_node'.
previously exported with '.export_node'.

:param workflow: The workflow instance the new node should
belong to.
Expand Down
4 changes: 2 additions & 2 deletions backend/src/baserow/contrib/automation/nodes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,14 @@ def get_next_nodes(

return self.workflow.get_graph().get_next_nodes(self, output_uid)

def get_children(self, specific=True):
def get_children(self):
"""
Returns the direct children of this node if any.
"""

from baserow.contrib.automation.nodes.handler import AutomationNodeHandler

return AutomationNodeHandler().get_children(self, specific=specific)
return AutomationNodeHandler().get_children(self)


class AutomationActionNode(AutomationNode):
Expand Down
32 changes: 21 additions & 11 deletions backend/src/baserow/contrib/automation/nodes/node_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def before_move(
output: str,
):
"""
Check the container node is not moved inside it self.
Check the container node is not moved inside itself.
"""

if node in reference_node.get_parent_nodes():
Expand All @@ -114,7 +114,8 @@ def before_move(


class LocalBaserowUpsertRowNodeType(AutomationNodeActionNodeType):
type = "upsert_row"
type = "local_baserow_upsert_row"
compat_type = "upsert_row"
service_type = LocalBaserowUpsertRowServiceType.type

def get_pytest_params(self, pytest_data_fixture) -> Dict[str, int]:
Expand All @@ -123,35 +124,41 @@ def get_pytest_params(self, pytest_data_fixture) -> Dict[str, int]:


class LocalBaserowCreateRowNodeType(LocalBaserowUpsertRowNodeType):
type = "create_row"
type = "local_baserow_create_row"
compat_type = "create_row"
model_class = LocalBaserowCreateRowActionNode


class LocalBaserowUpdateRowNodeType(LocalBaserowUpsertRowNodeType):
type = "update_row"
type = "local_baserow_update_row"
compat_type = "update_row"
model_class = LocalBaserowUpdateRowActionNode


class LocalBaserowDeleteRowNodeType(AutomationNodeActionNodeType):
type = "delete_row"
type = "local_baserow_delete_row"
compat_type = "delete_row"
model_class = LocalBaserowDeleteRowActionNode
service_type = LocalBaserowDeleteRowServiceType.type


class LocalBaserowGetRowNodeType(AutomationNodeActionNodeType):
type = "get_row"
type = "local_baserow_get_row"
compat_type = "get_row"
model_class = LocalBaserowGetRowActionNode
service_type = LocalBaserowGetRowUserServiceType.type


class LocalBaserowListRowsNodeType(AutomationNodeActionNodeType):
type = "list_rows"
type = "local_baserow_list_rows"
compat_type = "list_rows"
model_class = LocalBaserowListRowsActionNode
service_type = LocalBaserowListRowsUserServiceType.type


class LocalBaserowAggregateRowsNodeType(AutomationNodeActionNodeType):
type = "aggregate_rows"
type = "local_baserow_aggregate_rows"
compat_type = "aggregate_rows"
model_class = LocalBaserowAggregateRowsActionNode
service_type = LocalBaserowAggregateRowsUserServiceType.type

Expand Down Expand Up @@ -365,19 +372,22 @@ def on_event(


class LocalBaserowRowsCreatedNodeTriggerType(AutomationNodeTriggerType):
type = "rows_created"
type = "local_baserow_rows_created"
compat_type = "rows_created"
model_class = LocalBaserowRowsCreatedTriggerNode
service_type = LocalBaserowRowsCreatedServiceType.type


class LocalBaserowRowsUpdatedNodeTriggerType(AutomationNodeTriggerType):
type = "rows_updated"
type = "local_baserow_rows_updated"
compat_type = "rows_updated"
model_class = LocalBaserowRowsUpdatedTriggerNode
service_type = LocalBaserowRowsUpdatedServiceType.type


class LocalBaserowRowsDeletedNodeTriggerType(AutomationNodeTriggerType):
type = "rows_deleted"
type = "local_baserow_rows_deleted"
compat_type = "rows_deleted"
model_class = LocalBaserowRowsDeletedTriggerNode
service_type = LocalBaserowRowsDeletedServiceType.type

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def get_next_nodes(
if output is None or uid == output
]

def get_children(self, node) -> List[AutomationNode]:
def get_children(self, node: AutomationNode) -> List[AutomationNode]:
"""
Returns the node children.
"""
Expand Down
6 changes: 5 additions & 1 deletion backend/src/baserow/contrib/automation/workflows/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from django.utils import timezone

from loguru import logger
from opentelemetry import trace

from baserow.contrib.automation.automation_dispatch_context import (
AutomationDispatchContext,
Expand Down Expand Up @@ -48,6 +49,7 @@
from baserow.core.registries import ImportExportConfig
from baserow.core.services.exceptions import DispatchException
from baserow.core.storage import ExportZipFile, get_default_storage
from baserow.core.telemetry.utils import baserow_trace_methods
from baserow.core.trash.handler import TrashHandler
from baserow.core.utils import (
ChildProgressBuilder,
Expand All @@ -60,8 +62,10 @@
WORKFLOW_RATE_LIMIT_CACHE_PREFIX = "automation_workflow_{}"
AUTOMATION_WORKFLOW_CACHE_LOCK_SECONDS = 5

tracer = trace.get_tracer(__name__)

class AutomationWorkflowHandler:

class AutomationWorkflowHandler(metaclass=baserow_trace_methods(tracer)):
allowed_fields = ["name", "allow_test_run_until", "state"]

def get_workflow(
Expand Down
26 changes: 23 additions & 3 deletions backend/src/baserow/core/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ class Instance(object):
type: str
"""A unique string that identifies the instance."""

compat_type: str = ""
""" If this instance has been renamed, and we want to support
compatibility of the original `type`, implement it with `compat_type`. """

def __init__(self):
if not self.type:
raise ImproperlyConfigured("The type of an instance must be set.")
Expand Down Expand Up @@ -758,13 +762,29 @@ def get(self, type_name: str) -> InstanceSubClass:
:rtype: InstanceModelInstance
"""

# If the `type_name` isn't in the registry, we may raise DoesNotExist.
if type_name not in self.registry:
raise self.does_not_exist_exception_class(
type_name, f"The {self.name} type {type_name} does not exist."
)
# But first, we'll test to see if it matches an Instance's
# `compat_name`. If it does, we'll use that Instance's `type`.
type_name_via_compat = self.get_by_type_name_by_compat(type_name)
if type_name_via_compat:
type_name = type_name_via_compat
else:
raise self.does_not_exist_exception_class(
type_name, f"The {self.name} type {type_name} does not exist."
)

return self.registry[type_name]

def get_by_type_name_by_compat(self, compat_name: str) -> Optional[str]:
"""
Returns a registered instance's `type` by using the compatibility name.
"""

for instance in self.get_all():
if instance.compat_type == compat_name:
return instance.type

def get_by_type(self, instance_type: Type[InstanceSubClass]) -> InstanceSubClass:
return self.get(instance_type.type)

Expand Down
Loading
Loading