Skip to content

Adding metadata to events #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 29, 2025
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
98 changes: 90 additions & 8 deletions serverlessworkflow/sdk/state_machine_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from serverlessworkflow.sdk.transition_data_condition import TransitionDataCondition
from serverlessworkflow.sdk.end_data_condition import EndDataCondition

from transitions.extensions import HierarchicalMachine, GraphMachine
from transitions.extensions.nesting import NestedState
import warnings

Expand Down Expand Up @@ -260,7 +259,67 @@ def sleep_state_details(self):

def event_state_details(self):
if isinstance(self.current_state, EventState):
self.state_to_machine_state(["event_state", "state"])
state = self.state_to_machine_state(["event_state", "state"])
if self.get_actions:
if on_events := self.current_state.onEvents:
state.initial = [] if len(on_events) > 1 else on_events[0]
for i, oe in enumerate(on_events):
state.add_substate(
oe_state := self.state_machine.state_cls(
oe_name := f"onEvent {i}"
)
)

# define initial state
if i == 0 and len(on_events) > 1:
state.initial = [oe_state.name]
elif i == 0 and len(on_events) == 1:
state.initial = oe_state.name
else:
state.initial.append(oe_state.name)

event_names = []
for ie, event in enumerate(oe.eventRefs):
oe_state.add_substate(
ns := self.state_machine.state_cls(event)
)
ns.tags = ["event"]
self.get_action_event(state=ns, e_name=event)
event_names.append(event)

# define initial state
if ie == 0 and len(oe.eventRefs) > 1:
oe_state.initial = [event]
elif ie == 0 and len(oe.eventRefs) == 1:
oe_state.initial = event
else:
oe_state.initial.append(event)

if self.current_state.exclusive:
oe_state.add_substate(
ns := self.state_machine.state_cls(
action_name := f"action {ie}"
)
)
self.state_machine.add_transition(
trigger="",
source=f"{self.current_state.name}.{oe_name}.{event}",
dest=f"{self.current_state.name}.{oe_name}.{action_name}",
)
self.generate_actions_info(
machine_state=ns,
state_name=f"{self.current_state.name}.{oe_name}.{action_name}",
actions=oe.actions,
action_mode=oe.actionMode,
)
if not self.current_state.exclusive and oe.actions:
self.generate_actions_info(
machine_state=oe_state,
state_name=f"{self.current_state.name}.{oe_name}",
actions=oe.actions,
action_mode=oe.actionMode,
initial_states=event_names,
)

def foreach_state_details(self):
if isinstance(self.current_state, ForEachState):
Expand Down Expand Up @@ -353,6 +412,7 @@ def generate_actions_info(
state_name: str,
actions: List[Dict[str, Action]],
action_mode: str = "sequential",
initial_states: List[str] = [],
):
if self.get_actions:
parallel_states = []
Expand Down Expand Up @@ -387,7 +447,11 @@ def generate_actions_info(
ns := self.state_machine.state_cls(name)
)
ns.tags = ["event"]
self.get_action_event(state=ns, e_name=name)
self.get_action_event(
state=ns,
e_name=action.eventRef.triggerEventRef,
er_name=action.eventRef.resultEventRef,
)
if name:
if action_mode == "sequential":
if i < len(actions) - 1:
Expand Down Expand Up @@ -439,19 +503,36 @@ def generate_actions_info(
)
ns.tags = ["event"]
self.get_action_event(
state=ns, e_name=next_name
state=ns,
e_name=action.eventRef.triggerEventRef,
er_name=action.eventRef.resultEventRef,
)
self.state_machine.add_transition(
trigger="",
source=f"{state_name}.{name}",
dest=f"{state_name}.{next_name}",
)
if i == 0:
if i == 0 and not initial_states:
machine_state.initial = name
elif i == 0 and initial_states:
for init_s in initial_states:
self.state_machine.add_transition(
trigger="",
source=f"{state_name}.{init_s}",
dest=f"{state_name}.{name}",
)
elif action_mode == "parallel":
parallel_states.append(name)
if action_mode == "parallel":
if action_mode == "parallel" and not initial_states:
machine_state.initial = parallel_states
elif action_mode == "parallel" and initial_states:
for init_s in initial_states:
for ps in parallel_states:
self.state_machine.add_transition(
trigger="",
source=f"{state_name}.{init_s}",
dest=f"{state_name}.{ps}",
)

def get_action_function(self, state: NestedState, f_name: str):
if self.workflow.functions:
Expand All @@ -461,13 +542,14 @@ def get_action_function(self, state: NestedState, f_name: str):
state.metadata = {"function": current_function}
break

def get_action_event(self, state: NestedState, e_name: str):
def get_action_event(self, state: NestedState, e_name: str, er_name: str = ""):
if self.workflow.events:
for event in self.workflow.events:
current_event = event.serialize().__dict__
if current_event["name"] == e_name:
state.metadata = {"event": current_event}
break
if current_event["name"] == er_name:
state.metadata = {"result_event": current_event}

def subflow_state_name(self, action: Action, subflow: Workflow):
return (
Expand Down
3 changes: 0 additions & 3 deletions serverlessworkflow/sdk/state_machine_helper.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
from typing import List
from serverlessworkflow.sdk.workflow import Workflow
from serverlessworkflow.sdk.state_machine_generator import StateMachineGenerator
from transitions.extensions.diagrams import HierarchicalGraphMachine, GraphMachine
from serverlessworkflow.sdk.state_machine_extensions import (
CustomGraphMachine,
CustomHierarchicalGraphMachine,
)
from transitions.extensions.nesting import NestedState
from transitions.extensions.diagrams_base import BaseGraph


class StateMachineHelper:
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy