States & Transitions

Define FSM states with State and StatesGroup, and optionally enforce allowed transitions using state guards.

Defining States

states.py
from pyrogram_patch.fsm import State, StatesGroup

class Registration(StatesGroup):
    waiting_for_name = State()
    waiting_for_email = State()
    waiting_for_confirm = State()

# States auto-assign group name
print(Registration.waiting_for_name)  # "Registration:waiting_for_name"

Each State() declared inside a StatesGroup automatically gets its name set to the attribute name and its group set to the class name (via metaclass).

State Guards Optional

You can enforce valid transitions by defining a transitions dict in your StatesGroup. If a handler tries to transition to a state not in the allowed list, an InvalidStateTransition error is raised.

With state guards
class OrderFlow(StatesGroup):
    cart = State()
    checkout = State()
    payment = State()
    complete = State()

    # State guards: define allowed transitions
    transitions = {
        cart: [checkout],            # cart → checkout only
        checkout: [payment, cart],   # checkout → payment or back to cart
        payment: [complete],         # payment → complete only
        complete: [],                # complete is a terminal state
    }

# Valid: cart → checkout
await patch_helper.set_state(OrderFlow.checkout)  # ✅ OK

# Invalid: cart → payment (not allowed)
await patch_helper.set_state(OrderFlow.payment)  # ❌ InvalidStateTransition

Note: State guards are entirely optional. If you don't define a transitions dict, any state can transition to any other state. Guards are useful for complex flows where you want to prevent invalid jumps (e.g., skipping payment in an order flow).

Iterating States

# Iterate over all states in a group
for state in Registration:
    print(state)
# Registration:waiting_for_name
# Registration:waiting_for_email
# Registration:waiting_for_confirm

State Comparison

# States support equality with other States and strings
Registration.waiting_for_name == Registration.waiting_for_name  # True
Registration.waiting_for_name == "Registration:waiting_for_name"  # True

# States are hashable (usable as dict keys)
handlers = {Registration.waiting_for_name: handle_name}

API Reference

State

Property / MethodTypeDescription
namestrFull qualified name (e.g., "Group:state_name")
__eq__(other)boolCompare with another State or string
__hash__()intHash based on qualified name

StatesGroup

FeatureDescription
Class-level State() attributesAuto-assigned names and group reference
transitions dict OptionalMap of state → list of allowed target states
IterationIterate over all states: for s in MyGroup: ...