Конечный автомат состояний (FSM)¶
Менеджер состояний (FSM) в vk-bot позволяет реализовывать многошаговые сценарии
(формы, опросы, онбординг), закрепляя текущее состояние за каждым пользователем.
Данные состояний могут храниться в оперативной памяти (in-memory), Redis или PostgreSQL.
Основная концепция¶
VKBotFSM- граф переходов без состояния. Общий для всех пользователей.StateManager- сохраняет состояние каждого пользователя в хранилище.StateContext- интерфейс для обработчиков:state.set(),state.data,state.finish().
Объявление состояний¶
from vk_bot import StatesGroup
from vk_bot.state.manager import State
class Form(StatesGroup):
waiting_name = State()
waiting_age = State()
Использование состояний в обработчиках¶
from vk_bot import VKBot, types
from vk_bot.state.context import StateContext
bot = VKBot(token="...")
@bot.message_handler(commands=["start"])
def cmd_start(message: types.Message):
bot.set_state(message.from_id, Form.waiting_name)
bot.send_message(message.chat.id, "Как вас зовут?")
@bot.message_handler(state=Form.waiting_name)
def handle_name(message: types.Message, state: StateContext):
state.update(name=message.text)
state.set(Form.waiting_age)
bot.send_message(message.chat.id, "Сколько вам лет?")
@bot.message_handler(state=Form.waiting_age)
def handle_age(message: types.Message, state: StateContext):
data = state.data
state.finish()
bot.send_message(
message.chat.id,
f"Сохранено: {data['name']}, {message.text} лет.",
)
Хранилища состояний¶
In-memory (по умолчанию, без зависимостей):
bot = VKBot(token="...")
Redis:
from vk_bot import VKBot, RedisStorage
bot = VKBot(token="...", state_storage=RedisStorage())
PostgreSQL:
from vk_bot import PostgresStorage
bot = VKBot(
token="...",
state_storage=PostgresStorage("postgresql://user:pass@localhost/db"),
)
Граф FSM с переходами¶
Для строгого управления навигацией задайте явный граф FSM:
from vk_bot.state.fsm import VKBotFSM, FSMRegistry
fsm = VKBotFSM("registration")
fsm.set_initial("idle")
fsm.add_state("waiting_name")
fsm.add_state("waiting_age")
fsm.add_transition("idle", "waiting_name")
fsm.add_transition("waiting_name", "waiting_age")
FSMRegistry.register("registration", fsm)
API StateContext¶
Подробная документация класса StateContext доступна в API Reference.
Основные методы:
state.set(new_state)- перейти в новое состояниеstate.data- получить данные пользователяstate.update(**kwargs)- обновить данныеstate.finish()- сбросить состояние и данныеstate["key"]- чтение/запись данных как вdictstate.is_state(state)- проверить текущее состояниеstate.is_in_group(group)- проверить принадлежность к группе