pybotx-fsm
Конечный автомат (Finite state machine) для ботов на базе библиотеки pybotx.
Возможности
- Лёгкое создание графа состояний и их переключений.
- Передача данных в следующее состояние при явном вызове перехода.
Подготовка к установке
Для работы библиотеки необходим Redis, который уже встроен в последние версии коробки.
Установка
Используя poetry:
poetry add pybotx-fsm
Работа с графом состояний
- Создайте
enumдля возможных состояний автомата:
from enum import Enum, auto
from pybotx_fsm import FSMCollector
class LoginStates(Enum):
enter_email = auto()
enter_password = auto()
fsm = FSMCollector(LoginStates)
- Добавьте экземпляр автомата в мидлвари для того, чтобы бот мог использовать его:
Bot(
collectors=[
myfile.collector,
],
bot_accounts=[
BotAccountWithSecret(
# Не забудьте заменить эти учётные данные на настоящие,
# когда создадите бота в панели администратора.
id=UUID("123e4567-e89b-12d3-a456-426655440000"),
cts_url=cast(Any, "https://cts.example.com"),
secret_key="e29b417773f2feab9dac143ee3da20c5",
),
],
middlewares=[
FSMMiddleware([myfile.fsm], state_repo_key="redis_repo"),
],
)
- Добавьте в
bot.state.{state_repo_key}совместимый redis репозиторий:
bot.state.redis_repo = await RedisRepo.init(...)
- Создайте обработчики конкретных состояний:
@fsm.on(LoginStates.enter_email)
async def enter_email(message: IncomingMessage, bot: Bot) -> None:
email = message.body
if not check_user_exist(email):
await bot.answer_message("Wrong email, try again")
return
await message.state.fsm.change_state(LoginStates.enter_password, email=email)
await bot.answer_message("Enter your password")
@fsm.on(LoginStates.enter_password)
async def enter_password(message: IncomingMessage, bot: Bot) -> None:
email = message.state.fsm_storage.email
password = message.body
try:
login(email, password)
except IncorrectPasswordError:
await bot.answer_message("Wrong password, try again")
return
await message.state.fsm.drop_state()
await bot.answer_message("Success!")
- Передайте управление обработчику состояний из любого обработчика сообщений:
@collector.command("/login")
async def start_login(message: IncomingMessage, bot: Bot) -> None:
await bot.answer_message("Enter your email")
await message.state.fsm.change_state(LoginStates.enter_email)
Примеры
Минимальный пример бота с конечным автоматом
# Здесь и далее будут пропущены импорты и код, не затрагивающий
# непосредственно pybotx_fsm
class FsmStates(Enum):
EXAMPLE_STATE = auto()
fsm = FSMCollector(FsmStates)
@collector.command("/echo", description="Echo command")
async def help_command(message: IncomingMessage, bot: Bot) -> None:
await message.state.fsm.change_state(FsmStates.EXAMPLE_STATE)
await bot.answer_message("Input your text:")
@fsm.on(FsmStates.EXAMPLE_STATE)
async def example_state(message: IncomingMessage, bot: Bot) -> None:
user_text = message.body
await message.state.fsm.drop_state()
await bot.answer_message(f"Your text is {user_text}")
bot = Bot(
collectors=[
collector,
],
bot_accounts=[
BotAccountWithSecret(
# Не забудьте заменить эти учётные данные на настоящие,
# когда создадите бота в панели администратора.
id=UUID("123e4567-e89b-12d3-a456-426655440000"),
cts_url=cast(Any, "https://cts.example.com"),
secret_key="e29b417773f2feab9dac143ee3da20c5",
),
],
middlewares=[
FSMMiddleware([fsm], state_repo_key="redis_repo"),
],
)
Передача данных между состояниями
@fsm.on(FsmStates.INPUT_FIRST_NAME)
async def input_first_name(message: IncomingMessage, bot: Bot) -> None:
first_name = message.body
await message.state.fsm.change_state(
FsmStates.INPUT_LAST_NAME,
first_name=first_name,
)
await bot.answer_message("Input your last name:")
@fsm.on(FsmStates.INPUT_LAST_NAME)
async def input_last_name(message: IncomingMessage, bot: Bot) -> None:
first_name = message.state.fsm_storage.first_name
last_name = message.body
await message.state.fsm.drop_state()
await bot.answer_message(f"Hello {first_name} {last_name}!")
Release files for pybotx-fsm 0.7.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pybotx_fsm-0.7.1.tar.gz | 6.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pybotx_fsm-0.7.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.1 kB
Release files / pybotx_fsm-0.7.1.tar.gz
| Download URL | pybotx_fsm-0.7.1.tar.gz |
|---|---|
| Size | 6.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a589de1f1c4084ba8f06d95b5503596b4c7f0853f7df4aad217bf83ab7d086b4
|
|
BLAKE2b-256 checksum How to use checksums |
65801b9388866bfb622cf3ec1a07e5616f213f0f711df0eb0f7ae1ea767fbbaa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.3.2 CPython/3.13.1 Linux/6.8.0-1044-azure
|
Release files / pybotx_fsm-0.7.1-py3-none-any.whl
| Download URL | pybotx_fsm-0.7.1-py3-none-any.whl |
|---|---|
| Size | 8.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a2b98b4994b265ab2888ff0ea4c54076cfe1e2eb3da4be69a512babcd5a65a8b
|
|
BLAKE2b-256 checksum How to use checksums |
375fcd18692a95668ace60549c0c44348153e4ea8d70472eabddc45d6af150f0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.3.2 CPython/3.13.1 Linux/6.8.0-1044-azure
|