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}!")
Metadata
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 | Provenance | Actions |
|---|---|---|---|---|
| pybotx_fsm-0.7.1.tar.gz | 6.5 kB | Without provenance | Details for pybotx_fsm-0.7.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pybotx_fsm-0.7.1-py3-none-any.whl | Python 3 | none | any | Details for pybotx_fsm-0.7.1-py3-none-any.whl |
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
|
Security for pybotx-fsm 0.7.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.