plexus.cli.procedure.state_machine module
Procedure State Machine
Defines the state machine for Procedure workflow using python-statemachine library. This provides clean, validated state transitions and prevents invalid state changes.
- class plexus.cli.procedure.state_machine.ProcedureStateMachine(procedure_id: str, current_state: str | None = None, client=None)
Bases:
StateMachineState machine for Procedure workflow.
- States:
start: Initial state when procedure is created
evaluation: Running initial evaluation to gather metrics
hypothesis: Analyzing evaluation results and generating hypotheses
test: Testing hypothesis by generating and evaluating score version
insights: Analyzing test results and generating insights
completed: All work finished successfully
error: Procedure encountered an error
- Transitions:
begin: start → evaluation (start initial evaluation)
analyze: evaluation → hypothesis (begin hypothesis generation)
start_testing: hypothesis → test (begin testing hypothesis)
analyze_results: test → insights (analyze test results)
continue_iteration: insights → hypothesis (loop back for next round)
finish_from_insights: insights → completed (insights complete, no more iterations)
finish_from_hypothesis: hypothesis → completed (decided no testing needed)
fail_*: any state → error (error occurred)
retry_from_error: error → evaluation (retry after error)
restart_from_error: error → start (full restart after error)
Initialize state machine for a procedure.
- Args:
procedure_id: The procedure ID current_state: The current state (if resuming), or None for new procedure client: Optional PlexusDashboardClient for updating TaskStages
- __init__(procedure_id: str, current_state: str | None = None, client=None)
Initialize state machine for a procedure.
- Args:
procedure_id: The procedure ID current_state: The current state (if resuming), or None for new procedure client: Optional PlexusDashboardClient for updating TaskStages
- analyze
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- analyze_results
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- begin
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- completed
A State in a StateMachine describes a particular behavior of the machine. When we say that a machine is “in” a state, it means that the machine behaves in the way that state describes.
- Args:
- name: A human-readable representation of the state. Default is derived
from the name of the variable assigned to the state machine class. The name is derived from the id using this logic:
name = id.replace("_", " ").capitalize()
- value: A specific value to the storage and retrieval of states.
If specified, you can use It to map a more friendly representation to a low-level value.
- initial: Set
Trueif theStateis the initial one. There must be one and only one initial state in a statemachine. Defaults to
False.- final: Set
Trueif represents a final state. A machine can have optionally many final states. Final states have no transition starting from It. Defaults to
False.- enter: One or more callbacks assigned to be executed when the state is entered.
See actions.
- exit: One or more callbacks assigned to be executed when the state is exited.
See actions.
State is a core component on how this library implements an expressive API to declare StateMachines.
>>> from statemachine import State
Given a few states…
>>> draft = State("Draft", initial=True)
>>> producing = State("Producing")
>>> closed = State('Closed', final=True)
Transitions are declared using the
State.to()orState.from_()(reversed) methods.>>> draft.to(producing) TransitionList([Transition(State('Draft', ...
The result is a TransitionList. Don’t worry about this internal class. But the good thing is that it implements the
ORoperator to combine transitions, so you can use the|syntax to compound a list of transitions and assign to the same event.You can declare all transitions for a state in one single line …
>>> transitions = draft.to(draft) | producing.to(closed)
… and you can append additional transitions for a state to previous definitions.
>>> transitions |= closed.to(draft)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Producing', 'Closed'), ('Closed', 'Draft')]
There are handy shortcuts that you can use to express this same set of transitions.
The first one,
draft.to(draft), is also called a self-transition, and can be expressed using an alternative syntax:>>> draft.to.itself() TransitionList([Transition(State('Draft', ...
You can even pass a list of target states to declare at once all transitions starting from the same state.
>>> transitions = draft.to(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Draft', 'Producing'), ('Draft', 'Closed')]
Sometimes it’s easier to use the
State.from_()method:>>> transitions = closed.from_(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Closed'), ('Producing', 'Closed'), ('Closed', 'Closed')]
- continue_iteration
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- error
A State in a StateMachine describes a particular behavior of the machine. When we say that a machine is “in” a state, it means that the machine behaves in the way that state describes.
- Args:
- name: A human-readable representation of the state. Default is derived
from the name of the variable assigned to the state machine class. The name is derived from the id using this logic:
name = id.replace("_", " ").capitalize()
- value: A specific value to the storage and retrieval of states.
If specified, you can use It to map a more friendly representation to a low-level value.
- initial: Set
Trueif theStateis the initial one. There must be one and only one initial state in a statemachine. Defaults to
False.- final: Set
Trueif represents a final state. A machine can have optionally many final states. Final states have no transition starting from It. Defaults to
False.- enter: One or more callbacks assigned to be executed when the state is entered.
See actions.
- exit: One or more callbacks assigned to be executed when the state is exited.
See actions.
State is a core component on how this library implements an expressive API to declare StateMachines.
>>> from statemachine import State
Given a few states…
>>> draft = State("Draft", initial=True)
>>> producing = State("Producing")
>>> closed = State('Closed', final=True)
Transitions are declared using the
State.to()orState.from_()(reversed) methods.>>> draft.to(producing) TransitionList([Transition(State('Draft', ...
The result is a TransitionList. Don’t worry about this internal class. But the good thing is that it implements the
ORoperator to combine transitions, so you can use the|syntax to compound a list of transitions and assign to the same event.You can declare all transitions for a state in one single line …
>>> transitions = draft.to(draft) | producing.to(closed)
… and you can append additional transitions for a state to previous definitions.
>>> transitions |= closed.to(draft)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Producing', 'Closed'), ('Closed', 'Draft')]
There are handy shortcuts that you can use to express this same set of transitions.
The first one,
draft.to(draft), is also called a self-transition, and can be expressed using an alternative syntax:>>> draft.to.itself() TransitionList([Transition(State('Draft', ...
You can even pass a list of target states to declare at once all transitions starting from the same state.
>>> transitions = draft.to(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Draft', 'Producing'), ('Draft', 'Closed')]
Sometimes it’s easier to use the
State.from_()method:>>> transitions = closed.from_(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Closed'), ('Producing', 'Closed'), ('Closed', 'Closed')]
- evaluation
A State in a StateMachine describes a particular behavior of the machine. When we say that a machine is “in” a state, it means that the machine behaves in the way that state describes.
- Args:
- name: A human-readable representation of the state. Default is derived
from the name of the variable assigned to the state machine class. The name is derived from the id using this logic:
name = id.replace("_", " ").capitalize()
- value: A specific value to the storage and retrieval of states.
If specified, you can use It to map a more friendly representation to a low-level value.
- initial: Set
Trueif theStateis the initial one. There must be one and only one initial state in a statemachine. Defaults to
False.- final: Set
Trueif represents a final state. A machine can have optionally many final states. Final states have no transition starting from It. Defaults to
False.- enter: One or more callbacks assigned to be executed when the state is entered.
See actions.
- exit: One or more callbacks assigned to be executed when the state is exited.
See actions.
State is a core component on how this library implements an expressive API to declare StateMachines.
>>> from statemachine import State
Given a few states…
>>> draft = State("Draft", initial=True)
>>> producing = State("Producing")
>>> closed = State('Closed', final=True)
Transitions are declared using the
State.to()orState.from_()(reversed) methods.>>> draft.to(producing) TransitionList([Transition(State('Draft', ...
The result is a TransitionList. Don’t worry about this internal class. But the good thing is that it implements the
ORoperator to combine transitions, so you can use the|syntax to compound a list of transitions and assign to the same event.You can declare all transitions for a state in one single line …
>>> transitions = draft.to(draft) | producing.to(closed)
… and you can append additional transitions for a state to previous definitions.
>>> transitions |= closed.to(draft)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Producing', 'Closed'), ('Closed', 'Draft')]
There are handy shortcuts that you can use to express this same set of transitions.
The first one,
draft.to(draft), is also called a self-transition, and can be expressed using an alternative syntax:>>> draft.to.itself() TransitionList([Transition(State('Draft', ...
You can even pass a list of target states to declare at once all transitions starting from the same state.
>>> transitions = draft.to(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Draft', 'Producing'), ('Draft', 'Closed')]
Sometimes it’s easier to use the
State.from_()method:>>> transitions = closed.from_(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Closed'), ('Producing', 'Closed'), ('Closed', 'Closed')]
- fail_from_evaluation
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- fail_from_hypothesis
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- fail_from_insights
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- fail_from_start
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- fail_from_test
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- final_states = [State('Completed', id='completed', value='completed', initial=False, final=True)]
- finish_from_hypothesis
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- finish_from_insights
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- hypothesis
A State in a StateMachine describes a particular behavior of the machine. When we say that a machine is “in” a state, it means that the machine behaves in the way that state describes.
- Args:
- name: A human-readable representation of the state. Default is derived
from the name of the variable assigned to the state machine class. The name is derived from the id using this logic:
name = id.replace("_", " ").capitalize()
- value: A specific value to the storage and retrieval of states.
If specified, you can use It to map a more friendly representation to a low-level value.
- initial: Set
Trueif theStateis the initial one. There must be one and only one initial state in a statemachine. Defaults to
False.- final: Set
Trueif represents a final state. A machine can have optionally many final states. Final states have no transition starting from It. Defaults to
False.- enter: One or more callbacks assigned to be executed when the state is entered.
See actions.
- exit: One or more callbacks assigned to be executed when the state is exited.
See actions.
State is a core component on how this library implements an expressive API to declare StateMachines.
>>> from statemachine import State
Given a few states…
>>> draft = State("Draft", initial=True)
>>> producing = State("Producing")
>>> closed = State('Closed', final=True)
Transitions are declared using the
State.to()orState.from_()(reversed) methods.>>> draft.to(producing) TransitionList([Transition(State('Draft', ...
The result is a TransitionList. Don’t worry about this internal class. But the good thing is that it implements the
ORoperator to combine transitions, so you can use the|syntax to compound a list of transitions and assign to the same event.You can declare all transitions for a state in one single line …
>>> transitions = draft.to(draft) | producing.to(closed)
… and you can append additional transitions for a state to previous definitions.
>>> transitions |= closed.to(draft)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Producing', 'Closed'), ('Closed', 'Draft')]
There are handy shortcuts that you can use to express this same set of transitions.
The first one,
draft.to(draft), is also called a self-transition, and can be expressed using an alternative syntax:>>> draft.to.itself() TransitionList([Transition(State('Draft', ...
You can even pass a list of target states to declare at once all transitions starting from the same state.
>>> transitions = draft.to(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Draft', 'Producing'), ('Draft', 'Closed')]
Sometimes it’s easier to use the
State.from_()method:>>> transitions = closed.from_(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Closed'), ('Producing', 'Closed'), ('Closed', 'Closed')]
- initial_state
A State in a StateMachine describes a particular behavior of the machine. When we say that a machine is “in” a state, it means that the machine behaves in the way that state describes.
- Args:
- name: A human-readable representation of the state. Default is derived
from the name of the variable assigned to the state machine class. The name is derived from the id using this logic:
name = id.replace("_", " ").capitalize()
- value: A specific value to the storage and retrieval of states.
If specified, you can use It to map a more friendly representation to a low-level value.
- initial: Set
Trueif theStateis the initial one. There must be one and only one initial state in a statemachine. Defaults to
False.- final: Set
Trueif represents a final state. A machine can have optionally many final states. Final states have no transition starting from It. Defaults to
False.- enter: One or more callbacks assigned to be executed when the state is entered.
See actions.
- exit: One or more callbacks assigned to be executed when the state is exited.
See actions.
State is a core component on how this library implements an expressive API to declare StateMachines.
>>> from statemachine import State
Given a few states…
>>> draft = State("Draft", initial=True)
>>> producing = State("Producing")
>>> closed = State('Closed', final=True)
Transitions are declared using the
State.to()orState.from_()(reversed) methods.>>> draft.to(producing) TransitionList([Transition(State('Draft', ...
The result is a TransitionList. Don’t worry about this internal class. But the good thing is that it implements the
ORoperator to combine transitions, so you can use the|syntax to compound a list of transitions and assign to the same event.You can declare all transitions for a state in one single line …
>>> transitions = draft.to(draft) | producing.to(closed)
… and you can append additional transitions for a state to previous definitions.
>>> transitions |= closed.to(draft)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Producing', 'Closed'), ('Closed', 'Draft')]
There are handy shortcuts that you can use to express this same set of transitions.
The first one,
draft.to(draft), is also called a self-transition, and can be expressed using an alternative syntax:>>> draft.to.itself() TransitionList([Transition(State('Draft', ...
You can even pass a list of target states to declare at once all transitions starting from the same state.
>>> transitions = draft.to(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Draft', 'Producing'), ('Draft', 'Closed')]
Sometimes it’s easier to use the
State.from_()method:>>> transitions = closed.from_(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Closed'), ('Producing', 'Closed'), ('Closed', 'Closed')]
- insights
A State in a StateMachine describes a particular behavior of the machine. When we say that a machine is “in” a state, it means that the machine behaves in the way that state describes.
- Args:
- name: A human-readable representation of the state. Default is derived
from the name of the variable assigned to the state machine class. The name is derived from the id using this logic:
name = id.replace("_", " ").capitalize()
- value: A specific value to the storage and retrieval of states.
If specified, you can use It to map a more friendly representation to a low-level value.
- initial: Set
Trueif theStateis the initial one. There must be one and only one initial state in a statemachine. Defaults to
False.- final: Set
Trueif represents a final state. A machine can have optionally many final states. Final states have no transition starting from It. Defaults to
False.- enter: One or more callbacks assigned to be executed when the state is entered.
See actions.
- exit: One or more callbacks assigned to be executed when the state is exited.
See actions.
State is a core component on how this library implements an expressive API to declare StateMachines.
>>> from statemachine import State
Given a few states…
>>> draft = State("Draft", initial=True)
>>> producing = State("Producing")
>>> closed = State('Closed', final=True)
Transitions are declared using the
State.to()orState.from_()(reversed) methods.>>> draft.to(producing) TransitionList([Transition(State('Draft', ...
The result is a TransitionList. Don’t worry about this internal class. But the good thing is that it implements the
ORoperator to combine transitions, so you can use the|syntax to compound a list of transitions and assign to the same event.You can declare all transitions for a state in one single line …
>>> transitions = draft.to(draft) | producing.to(closed)
… and you can append additional transitions for a state to previous definitions.
>>> transitions |= closed.to(draft)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Producing', 'Closed'), ('Closed', 'Draft')]
There are handy shortcuts that you can use to express this same set of transitions.
The first one,
draft.to(draft), is also called a self-transition, and can be expressed using an alternative syntax:>>> draft.to.itself() TransitionList([Transition(State('Draft', ...
You can even pass a list of target states to declare at once all transitions starting from the same state.
>>> transitions = draft.to(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Draft', 'Producing'), ('Draft', 'Closed')]
Sometimes it’s easier to use the
State.from_()method:>>> transitions = closed.from_(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Closed'), ('Producing', 'Closed'), ('Closed', 'Closed')]
- name = 'ProcedureStateMachine'
- on_analyze()
Called when transitioning evaluation → hypothesis
- on_analyze_results()
Called when transitioning test → insights
- on_begin()
Called when transitioning start → evaluation
- on_continue_iteration()
Called when transitioning insights → hypothesis (looping back for next round)
- on_enter_error()
Called when entering error state
- on_finish_from_hypothesis()
Called when transitioning hypothesis → completed
- on_finish_from_insights()
Called when transitioning insights → completed
- on_restart_from_error()
Called when transitioning error → start
- on_retry_from_error()
Called when transitioning error → evaluation
- on_start_testing()
Called when transitioning hypothesis → test
- restart_from_error
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- retry_from_error
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- start
A State in a StateMachine describes a particular behavior of the machine. When we say that a machine is “in” a state, it means that the machine behaves in the way that state describes.
- Args:
- name: A human-readable representation of the state. Default is derived
from the name of the variable assigned to the state machine class. The name is derived from the id using this logic:
name = id.replace("_", " ").capitalize()
- value: A specific value to the storage and retrieval of states.
If specified, you can use It to map a more friendly representation to a low-level value.
- initial: Set
Trueif theStateis the initial one. There must be one and only one initial state in a statemachine. Defaults to
False.- final: Set
Trueif represents a final state. A machine can have optionally many final states. Final states have no transition starting from It. Defaults to
False.- enter: One or more callbacks assigned to be executed when the state is entered.
See actions.
- exit: One or more callbacks assigned to be executed when the state is exited.
See actions.
State is a core component on how this library implements an expressive API to declare StateMachines.
>>> from statemachine import State
Given a few states…
>>> draft = State("Draft", initial=True)
>>> producing = State("Producing")
>>> closed = State('Closed', final=True)
Transitions are declared using the
State.to()orState.from_()(reversed) methods.>>> draft.to(producing) TransitionList([Transition(State('Draft', ...
The result is a TransitionList. Don’t worry about this internal class. But the good thing is that it implements the
ORoperator to combine transitions, so you can use the|syntax to compound a list of transitions and assign to the same event.You can declare all transitions for a state in one single line …
>>> transitions = draft.to(draft) | producing.to(closed)
… and you can append additional transitions for a state to previous definitions.
>>> transitions |= closed.to(draft)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Producing', 'Closed'), ('Closed', 'Draft')]
There are handy shortcuts that you can use to express this same set of transitions.
The first one,
draft.to(draft), is also called a self-transition, and can be expressed using an alternative syntax:>>> draft.to.itself() TransitionList([Transition(State('Draft', ...
You can even pass a list of target states to declare at once all transitions starting from the same state.
>>> transitions = draft.to(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Draft', 'Producing'), ('Draft', 'Closed')]
Sometimes it’s easier to use the
State.from_()method:>>> transitions = closed.from_(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Closed'), ('Producing', 'Closed'), ('Closed', 'Closed')]
- start_testing
An event is triggers a signal that something has happened.
They are send to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also events.
- property state_value: str
Get the current state value as a string
- states = [State('Start', id='start', value='start', initial=True, final=False), State('Evaluation', id='evaluation', value='evaluation', initial=False, final=False), State('Hypothesis', id='hypothesis', value='hypothesis', initial=False, final=False), State('Test', id='test', value='test', initial=False, final=False), State('Insights', id='insights', value='insights', initial=False, final=False), State('Completed', id='completed', value='completed', initial=False, final=True), State('Error', id='error', value='error', initial=False, final=False)]
- states_map = {'completed': State('Completed', id='completed', value='completed', initial=False, final=True), 'error': State('Error', id='error', value='error', initial=False, final=False), 'evaluation': State('Evaluation', id='evaluation', value='evaluation', initial=False, final=False), 'hypothesis': State('Hypothesis', id='hypothesis', value='hypothesis', initial=False, final=False), 'insights': State('Insights', id='insights', value='insights', initial=False, final=False), 'start': State('Start', id='start', value='start', initial=True, final=False), 'test': State('Test', id='test', value='test', initial=False, final=False)}
- test
A State in a StateMachine describes a particular behavior of the machine. When we say that a machine is “in” a state, it means that the machine behaves in the way that state describes.
- Args:
- name: A human-readable representation of the state. Default is derived
from the name of the variable assigned to the state machine class. The name is derived from the id using this logic:
name = id.replace("_", " ").capitalize()
- value: A specific value to the storage and retrieval of states.
If specified, you can use It to map a more friendly representation to a low-level value.
- initial: Set
Trueif theStateis the initial one. There must be one and only one initial state in a statemachine. Defaults to
False.- final: Set
Trueif represents a final state. A machine can have optionally many final states. Final states have no transition starting from It. Defaults to
False.- enter: One or more callbacks assigned to be executed when the state is entered.
See actions.
- exit: One or more callbacks assigned to be executed when the state is exited.
See actions.
State is a core component on how this library implements an expressive API to declare StateMachines.
>>> from statemachine import State
Given a few states…
>>> draft = State("Draft", initial=True)
>>> producing = State("Producing")
>>> closed = State('Closed', final=True)
Transitions are declared using the
State.to()orState.from_()(reversed) methods.>>> draft.to(producing) TransitionList([Transition(State('Draft', ...
The result is a TransitionList. Don’t worry about this internal class. But the good thing is that it implements the
ORoperator to combine transitions, so you can use the|syntax to compound a list of transitions and assign to the same event.You can declare all transitions for a state in one single line …
>>> transitions = draft.to(draft) | producing.to(closed)
… and you can append additional transitions for a state to previous definitions.
>>> transitions |= closed.to(draft)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Producing', 'Closed'), ('Closed', 'Draft')]
There are handy shortcuts that you can use to express this same set of transitions.
The first one,
draft.to(draft), is also called a self-transition, and can be expressed using an alternative syntax:>>> draft.to.itself() TransitionList([Transition(State('Draft', ...
You can even pass a list of target states to declare at once all transitions starting from the same state.
>>> transitions = draft.to(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Draft', 'Producing'), ('Draft', 'Closed')]
Sometimes it’s easier to use the
State.from_()method:>>> transitions = closed.from_(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Closed'), ('Producing', 'Closed'), ('Closed', 'Closed')]
- plexus.cli.procedure.state_machine.create_state_machine(procedure_id: str, current_state: str | None = None, client=None) ProcedureStateMachine
Create a state machine for a procedure.
- Args:
procedure_id: The procedure ID current_state: The current state (if resuming), or None for new procedure client: Optional PlexusDashboardClient for TaskStage updates
- Returns:
ProcedureStateMachine instance
- plexus.cli.procedure.state_machine.get_valid_transitions(current_state: str | None) list[str]
Get list of valid transitions from a given state.
- Args:
current_state: The current state value
- Returns:
List of valid next state values
- plexus.cli.procedure.state_machine.is_valid_transition(from_state: str | None, to_state: str) bool
Check if a state transition is valid.
- Args:
from_state: The current state (or None for initial state) to_state: The target state
- Returns:
True if transition is valid, False otherwise