Skip to main content

pybotx-fsm

codecov

Конечный автомат (Finite state machine) для ботов на базе библиотеки pybotx.

Возможности

  • Лёгкое создание графа состояний и их переключений.
  • Передача данных в следующее состояние при явном вызове перехода.

Подготовка к установке

Для работы библиотеки необходим Redis, который уже встроен в последние версии коробки.

Установка

Используя poetry:

poetry add pybotx-fsm

Работа с графом состояний

  1. Создайте enum для возможных состояний автомата:
from enum import Enum, auto

from pybotx_fsm import FSMCollector


class LoginStates(Enum):
    enter_email = auto()
    enter_password = auto()


fsm = FSMCollector(LoginStates)
  1. Добавьте экземпляр автомата в мидлвари для того, чтобы бот мог использовать его:
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"),
    ],
)
  1. Добавьте в bot.state.{state_repo_key} совместимый redis репозиторий:
bot.state.redis_repo = await RedisRepo.init(...)
  1. Создайте обработчики конкретных состояний:
@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!")
  1. Передайте управление обработчику состояний из любого обработчика сообщений:
@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}!")

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pybotx_fsm-0.7.1.tar.gz (6.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pybotx_fsm-0.7.1-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file pybotx_fsm-0.7.1.tar.gz.

File metadata

  • Download URL: pybotx_fsm-0.7.1.tar.gz
  • Upload date:
  • Size: 6.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.13.1 Linux/6.8.0-1044-azure

File hashes

Hashes for pybotx_fsm-0.7.1.tar.gz
Algorithm Hash digest
SHA256 a589de1f1c4084ba8f06d95b5503596b4c7f0853f7df4aad217bf83ab7d086b4
MD5 98e37252deb766314588e0c528e10835
BLAKE2b-256 65801b9388866bfb622cf3ec1a07e5616f213f0f711df0eb0f7ae1ea767fbbaa

See more details on using hashes here.

File details

Details for the file pybotx_fsm-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: pybotx_fsm-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 8.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.13.1 Linux/6.8.0-1044-azure

File hashes

Hashes for pybotx_fsm-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a2b98b4994b265ab2888ff0ea4c54076cfe1e2eb3da4be69a512babcd5a65a8b
MD5 390a7944c68103c82638fc213578ee83
BLAKE2b-256 375fcd18692a95668ace60549c0c44348153e4ea8d70472eabddc45d6af150f0

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.7.1 This release

2 files

0.7.0

2 files

0.6.1

2 files

0.6.0

2 files

0.5.0

2 files

0.4.12

2 files

0.4.11

2 files

0.4.10

2 files

0.4.9

2 files

0.4.8

2 files

0.4.7

2 files

0.4.6

2 files

0.4.5

2 files

0.4.4

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.8

2 files

0.3.7

2 files

0.3.6

2 files

0.3.5

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page